将浮点数与零进行比较

时间:2010-12-03 20:36:01

标签: c floating-point

我想检查一个IEEE754 32位数字是否具有正好0.0f的值(它偶尔会被设置为它。)累积误差将为零,因为数据将经常从传感器更新。我的处理器没有硬件FPU,因此操作在相当快的软件库中完成。但是,对于添加,减去和比较等事情,它仍然有数百个周期。

所以我想知道为什么我的编译器会这样做:

240:                 if(p_viewer->roll != 0.0f)
 03FBC  B81160     mul.uu w2,#0,w2
 03FBE  900A2E     mov.w [w14+20],w4
 03FC0  900064     mov.w [w4+12],w0
 03FC2  9000F4     mov.w [w4+14],w1
 03FC4  07E91F     rcall __nesf2
 03FC6  E00000     cp0.w w0
 03FC8  320054     bra z, 0x004072

__ nesf2显然比较了两个浮点数。为什么不对整数形式的0.0f进行比较,即0x00000000?有什么理由不这样做,还是只是错过了优化机会?

我的编译器是MPLAB C30,GCC v3.23的一个版本。

4 个答案:

答案 0 :(得分:7)

因为-0.0f也按照IEEE-754标准的要求比较等于0.0f

如果这是一个主要的性能问题,您可以使用与-0(0x80000000)和+0的整数表示进行比较来替换调用。 (或者更好的是,屏蔽符号位并与0.0f进行比较)。

答案 1 :(得分:1)

如果这是一个IEEE浮点实现,它必须考虑信号NAN的。

您可能不关心这一点,但编译器不知道这一点。

答案 2 :(得分:1)

这是一个错过的优化机会。 0.f是一种特殊情况,因为它必须与-0.f和0.f进行比较。但是,作为整体进行比较仍然会更快。

为什么没有优化?我打赌这是一个整合问题。像这样的东西通常落在椅子之间。有权组建平台SDK的人选择一个编译器(gcc),一个软件浮动库,并设法以最佳方式将它们粘合在一起。这在一般情况下工作正常,并且几乎没有改进的动力,因为软件浮动通常是非常慢的。最糟糕的部分不是比较,而是所有其他的东西。

简单地说,如果你有软件浮动,如果你需要性能,没有必要使用它们。使用固定点。

答案 3 :(得分:0)

要检查0.0f,您不需要IEEE内容,例如:

int isFloatNull(float f)
{
  static float i;
  return !memcmp(&i,&f,sizeof i);
}