通过作弊快速比较IEEE浮点数大于零

时间:2014-11-26 04:33:20

标签: c++ optimization floating-point compare ieee

我正在研究一个平台,当将浮点数与零比较时,这个平台会出现可怕的停顿。作为优化,我看到使用了以下代码:

inline bool GreaterThanZero( float value )
{
   const int value_as_int = *(int*)&value;
   return ( value_as_int > 0 );
}

查看生成的程序集,档位消失了,功能更加高效。

这有用吗?我很困惑,因为IEEE技巧的所有优化都使用SIGNMASKS和许多AND / OR操作(例如http://www.lomont.org/Math/Papers/2005/CompareFloat.pdf)。对有符号int的强制转换是否有帮助?在简单的线束中进行测试没有发现问题。

任何见解都会很好。

1 个答案:

答案 0 :(得分:6)

表达式*(int*)&value > 0测试value是否为任何正浮点数,从最小的正规范(具有与0x00000001相同的表示)到最大的有限浮点数(带有表示{{ 1}})和0x7f7fffff(与+inf具有相同的表示形式)。该技巧检测到多个(但不是全部)NaN表示为正(NaN表示高于0x7f800000)。如果您不关心某些NaN值使测试成立,那就没问题了。

这一切都有效,因为IEEE {754格式的representation

为了模拟IEEE 754操作,您在文献中看到的位操作函数可能旨在实现完美仿真,同时考虑0x7f800001和带符号零的特定行为。例如,变体NaN不等同于*(int*)&value >= 0,因为value >= 0.0f表示为-0.0f作为无符号整数,因此0x80000000表示为已签名一,使后一种情况成立,前者成为假。这可能会使这些功能变得非常复杂。

  

投射到签名的-0x80000000有帮助吗?

嗯,是的,因为intfloat的符号位在同一个地方,并且两者都表示未设置时为正数。但条件int可以通过将value > 0.0f重新解释为无符号整数来实现。


注意:转换为value地址的int*会破坏严格的别名规则,但如果您的编译器保证它为这些程序赋予意义(可能使用命令行),这可能是可以接受的选项)。