可以选择ceil()和floor()来获取最接近的整数值,在浮点值的上方和下方?
我正在为C中的可以选择ceil()和floor()来获取最接近的整数值,在浮点值的上方和下方?,c,algorithm,floor,ceil,C,Algorithm,Floor,Ceil,我正在为C中的ceil()和floor()函数寻找一种替代方法,因为我不允许在项目中使用这些函数 到目前为止,我所构建的是一种复杂的来回转换方式,通过使用cast运算符,将浮点值(在我的例子中是double)转换为int,然后我需要最接近的整数,在给定浮点值的上方和下方,也就是double值,返回到双倍 #include <stdio.h> int main(void) { double original = 124.576; double floorint; d
ceil()
和floor()
函数寻找一种替代方法,因为我不允许在项目中使用这些函数
到目前为止,我所构建的是一种复杂的来回转换方式,通过使用cast运算符,将浮点值(在我的例子中是double
)转换为int
,然后我需要最接近的整数,在给定浮点值的上方和下方,也就是double
值,返回到双倍
#include <stdio.h>
int main(void) {
double original = 124.576;
double floorint;
double ceilint;
int f;
int c;
f = (int)original; //Truncation to closest floor integer value
c = f + 1;
floorint = (double)f;
ceilint = (double)c;
printf("Original Value: %lf, Floor Int: %lf , Ceil Int: %lf", original, floorint, ceilint);
}
对于本例,通常我不需要将c
和f
的ceil和floor整数值转换回double
,但在实际程序中,我需要它们位于double
中。将此视为任务的要求。
虽然输出给出了所需的值,并且到目前为止似乎是正确的,但我仍然担心这种方法是否真的那么正确和合适,或者更清楚地说,如果这种方法确实给程序带来了任何不良行为或问题,或者与其他替代方法相比,给我带来了性能损失,如果有其他可能的替代方案
你知道更好的选择吗?如果是这样的话,为什么这个会更好
非常感谢。您错过了一个重要步骤:您需要检查数字是否已经是整数,因此对于
ceil
假设非负数(泛化很简单),请使用
double ceil(double f){
if (f >= LLONG_MAX){
// f will be integral unless you have a really funky platform
return f;
} else {
long long i = f;
return 0.0 + i + (f != i); // to obviate potential long long overflow
}
}
拼图中的另一个缺失部分是检查f
是否在long
的范围内,这一点已被我随函附上的if
所覆盖。在通用平台上,如果f
超出了long
的界限,那么它无论如何都是整数
请注意,floor
是微不足道的,因为对long
的截断总是接近零
你知道更好的选择吗?如果是这样的话,为什么这个会更好
操作代码失败:
已经是一个整数original
是负片,类似于original
。截断不存在-1.5
刚好在original
范围之外int
不是数字原件
替代结构
双倍我的手机(双倍x)
当x
超出整数范围时,对某些整数类型使用强制转换技巧是一个问题。因此,首先检查x
是否在足够宽的整数范围内(精度超过double
)x
值超出已为整数的范围。建议选择最宽的整数(u)intmax\u t
请记住,对整数的转换是朝向0的圆,而不是地板。当代码为ceil()
或floor()
时,如果x
为负/正,则需要进行不同的处理。OP的密码漏掉了这个
如果(x>=INTMAX\u MAX){涉及的(double)INTMAX\u MAX
的四舍五入和精确值是“以实现定义的方式选择的”,我会避免,相反,我会与INTMAX\u MAX\u P1
进行比较,一些整数\u MAX
是a,如果是2的补码,…MIN
是一个否定的值“2的力量”
\u mm\u round\u sd
如果seriously@Sopel我该怎么处理\u mm\u round\u sd
?@RobertS,如果输入是124怎么办!!!!@ManthanTilva好吧,我想,你是对的,我应该提供一个条件,如果原始值为“真”,ceil值只能是地板值的+1“浮点值。否则ceil值应该与下限值相等。对于下限值,在这种情况下应该没有重要区别。@RobertS:当然。这就是表达式0.0+i+(f!=i)的含义。”
在我的回答中是这样的。首先非常感谢你的回答。为什么这两件事对这个案例如此重要?为什么我忽略它们会很糟糕?这对我来说不是很清楚。~@RobertS:我现在的版本很好,假设64位IEEE754浮点双精度。还有一个难题是如何处理NaNs和infi缺点。@th33lf:的确。编写一个可移植的ceil
是一件痛苦的事。C标准库很容易忽略可移植性。但是你仍然应该将上面的测试改为if(f=LLONG_MAX){….非常感谢你的深入解释。是的,这就是我所要求的,因为作为一个初学者,我不知道所有的情况。我需要一段时间来完成单独的步骤并详细理解它们。非常感谢你,chux!@chqrlie是的-那更好。
double ceil(double f){
if (f >= LLONG_MAX){
// f will be integral unless you have a really funky platform
return f;
} else {
long long i = f;
return 0.0 + i + (f != i); // to obviate potential long long overflow
}
}
#include <inttypes.h>
#define INTMAX_MAX_P1 ((INTMAX_MAX/2 + 1)*2.0)
double my_ceil(double x) {
if (x >= INTMAX_MAX_P1) {
return x;
}
if (x < INTMAX_MIN) {
return x;
}
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i < 0 || x == i) return i; // negative x is already rounded up.
return i + 1.0;
}
double my_ceil(double x) {
if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i < 0 || x == i) return i; // negative x is already rounded up.
return i + 1.0;
}
return x;
}
double my_floor(double x) {
if (x >= INTMAX_MIN && x < INTMAX_MAX_P1) {
intmax_t i = (intmax_t) x; // this rounds towards 0
if (i > 0 || x == i) return i; // positive x is already rounded down.
return i - 1.0;
}
return x;
}