3

我正在一个平台上工作,当将浮点数与零进行比较时,它会出现严重的停顿。作为优化,我看到使用了以下代码:

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

查看生成的程序集,停顿消失了,功能更高效。

这行得通吗?我很困惑,因为 IEEE 技巧的所有优化都使用 SIGNMASKS 和大量 AND/OR 操作(例如https://www.lomont.org/papers/2005/CompareFloat.pdf )。强制转换为带符号的 int 有帮助吗?在简单的线束中进行测试没有发现任何问题。

任何见解都会很好。

4

1 回答 1

8

该表达式*(int*)&value > 0测试是否value是任何正浮点数,从最小的正非正规(与 具有相同的表示0x00000001)到最大的有限浮点(具有表示0x7f7fffff)和+inf(与 具有相同的表示0x7f800000)。该技巧将许多但不是全部的 NaN 表示(上面的 NaN 表示0x7f800001)检测为正数。如果您不关心 NaN 的某些值使测试为真,那很好。

由于IEEE 754 格式的表示,这一切都有效。

您在文献中看到的用于模拟 IEEE 754 操作的位操作函数可能旨在完美模拟,同时考虑到带NaN符号零的特定行为。例如,变化*(int*)&value >= 0将不等价于value >= 0.0f,因为-0.0f,表示为0x80000000无符号整数,因此表示为有符号整数-0x80000000,使后一个条件为真而前一个条件为假。这会使这些功能变得相当复杂。

演员表签名有int帮助吗?

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


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

于 2014-11-26T06:41:45.377 回答