我想检查一个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的一个版本。
答案 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);
}