我正在寻找 C 中 ceil()
和 floor()
函数的替代方案,因为我不允许在项目中使用这些函数。
到目前为止,我所构建的是一种棘手的来回方式,即使用强制转换运算符,并将浮点值(在我的例子中为 double
)转换为int
及以后,因为我需要高于和低于给定浮点值的最接近的整数也是 double
值,回到 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);
}
输出:
Original Value: 124.576000, Floor Int: 124.000000 , Ceil Int: 125.000000
对于这个例子,通常我不需要将c
和f
的ceil和floor整数值转换回double
,但我在我的实际程序中需要将它们放在 double 中。将此视为任务的要求。
虽然输出给出了所需的值并且到目前为止看起来是正确的,但我仍然担心这种方法是否真的那么正确和合适,或者更清楚地说,这种方法是否确实带来了任何不良行为或问题如果还有其他可能的替代方案,那么与其他替代方案相比,我会损失性能。
<小时/>你知道更好的选择吗?如果是这样,为什么这个应该更好?
非常感谢。
最佳答案
Do you know a better alternative? And if so, why this one should be better?
OP'代码失败:
original
已经是一个整数。original
是一个负数,例如-1.5
。截断并不存在。original
刚好超出int
范围。原始
不是数字。
替代结构
双 my_ceil(双 x)
当 x 超出整数范围时,使用转换为某些整数类型技巧会出现问题。因此,首先检查x
是否在足够宽的整数范围内(其精度超过double
)。除此以外的 x
值已经是整数。建议选择最宽的整数 (u)intmax_t
。
请记住,转换为整数是向 0 舍入,而不是向下取整。当代码为 ceil()
或 floor()
时,如果 x
为负/正,则需要不同的处理。 OP 的代码错过了这一点。
我会避免使用 if (x >= INTMAX_MAX) {
因为这涉及 (double) INTMAX_MAX
,其舍入和精确值是“在实现定义中选择的”方式”。相反,我会与 INTMAX_MAX_P1
进行比较。 some_integer_MAX
是 Mersenne Number对于 2 的补码,...MIN
是“2 的幂”的负数。
#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;
}
因为x
可能是not-a-number ,反转比较更有用,因为 NaN 的关系比较为 false。
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;
}
关于c - 替代 ceil() 和 Floor() 来获取浮点值上方和下方最接近的整数值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59321732/