2013-04-18 23 views
2

是否有巧妙的表达式技巧来测试float vec3是否是轴向(即两个零分量)而不使用多次相等性测试?在没有多次测试的情况下测试两个浮点数是否为零

起初我想到if(abs(x)+abs(y)==0.0)(伪代码)...但当然每个abs调用可能会做分支/平等测试。

我想掩蔽每个浮点的字节一起和测试结果的,但IEEE FP具有正的和负0

回答

3

不,没有一种聪明的方法来测试三个IEEE-754二进制浮点值中的两个是否为零而没有将多个比较归零。

期望的结果是真当且仅当至少两种以下的为真:

  • 除了符号位所有X位为零。
  • 所有位除符号位为零外。
  • 所有位z除符号位为零外。

在评估“所有位”标准之前,没有按位操作可以帮助对此进行评估。任何丢失相同值中位之间关系的按位操作都是无用的。实质上,您需要分别了解以上各项的。但是,上述各项相当于将浮点比较为零。

你可以考虑数学方法,而不是按位:(| X | + | Ÿ |)•(| Ÿ | + | ž |)•(| ž | + | x |)在数学上为零,如果至少两个x,yz为零。取绝对值不需要比较;它可以通过清除符号位来实现。因此,以上可以实现为三个清零操作(并且在某些机器上,从浮点寄存器传输到通用寄存器并返回),三个浮点加法,两个乘法和一个比较。但是,乘法运算可能会下溢(即使精确的数学结果不为零,也会产生零)或溢出(当第一次乘法产生无穷大时会导致第二次乘法产生NaN,这是一个问题)。

在普通的现代处理器上进行比较并不昂贵,而且您通常不应该为避免它们而担心。分支可能很昂贵,但您可能不会注意到这是常规代码。如果某个分支在您的应用程序中证明是麻烦的,则可能会有处理器特定的方法来缓解该问题。可能有机器指令允许您获取比较结果作为可以执行逻辑操作的值,然后您只需要一条分支指令。这不是您应该执行的优化,除非您明确确定分支在您的应用程序中是一个重大问题。

+0

是的,经过进一步的测试,你是对的。感谢您的回应。 –

-1

埃里克Postpischil正确地射中我发布的代码的孔;它检查每个位是否出现在三个参数中的最多一个中。不幸的是,我想不出一个好办法来解决你的问题。

浮点绝对值可以(忽略NaNs)通过屏蔽掉符号位来实现,所以你也许可以使用它。此外,像==这样的比较可以编译成一个有条件的移动,而不是一些分支。

相关问题