在C语言中,floor()和ceil()函数与将数字转换为整数的强制类型转换之间有什么区别?

8

我正在编写一些C代码,用于将浮点数重复向上和向下舍入到整数值。标准的C数学库包括函数floor()ceil()。 我注意到更快的实现这些函数的方法是直接转换为整数:

int up, down;
float test = 1.3548;

up = (int)(test + 1);  //ceil()
down  = (int)test;     //floor()

我做了一个快速的检查,这看起来运行良好。

  1. 如果我需要结果作为整数作为数组索引(即它是否总是返回正确的结果),这是舍入上下的可靠方法吗?
  2. 这种方法为什么速度明显增加?(在我的系统上,它比math.h实现运行约快3倍)

9
不是一种可靠的方法。考虑test为整数值(如4.0)的情况。此时floor(x) == ceil(x),但您的代码将返回up = 5; down = 4。请您注意不要改变原文意思。 - njuffa
1
你确定这样更快吗?给我们展示一下你的性能测试! - Sulthan
取决于您所说的“可靠”是什么意思。如果“可靠”意味着“它会工作”,那么是的。但是,如果您的意思是更多,比如“它总是向下/向上/最接近/向零等舍入...”,那么不是...请确保在正数和负数以及可能超出'int'范围的数字上尝试各种方法,以查看会发生什么,以便您可以为特定情况选择“正确”的方法...哦,那应该是up =(int)(test + 0.5)-好好想想... - twalberg
如果您不关心旧处理器,请使用SSE4.1进行编译。然后,floor()ceil()将不再缓慢。 - Mysticial
1个回答

8

ceil()floor() 函数返回的数字与使用 round() 函数返回的不同。

up = (int)(test + 1);
down  = (int)test;

当你有一个负数时。

如果你有:

float test = -1.3548;
up = (int)test;        // ceil()
down = (int)(test-1);  // floor()

即使最后一种情况下,当test为整数时,这不是一个好的计算floor()的方法。
除非你希望以不同方式处理正数和负数,并且当test是整数时的特殊情况,否则最好使用ceil()和floor()。

1
对于round()函数,请使用(int)(test + 0.5f) - Iggy
3
对于整数负数,(int)(test - 1)floor()不等价。 - The Paramagnetic Croissant
1
@Iggy 对于 round() 使用:(int)(test + 0.5f) 在负数情况下会失败。 - chux - Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接