在没有多次测试的情况下测试两个浮点数是否为零

时间:2013-04-18 22:45:02

标签: floating-point equality pseudocode bitmask

是否有一个聪明的表达技巧来测试浮动vec3是否是轴向(即两个零组件)而不使用多个相等测试?

起初我想到了if(abs(x)+abs(y)==0.0)(伪代码)......但是当然每个abs调用都可能进行分支/相等测试。

我想把每个浮点数的字节屏蔽在一起并测试结果,但IEEE FP有正负0。

2 个答案:

答案 0 :(得分:3)

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

如果满足以下至少两项,则所需结果为真:

  • x 除符号位以外的所有位都为零。
  • 除了符号位之外的 y 的所有位都为零。
  • z 除符号位以外的所有位均为零。

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

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

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

答案 1 :(得分:-1)

Eric Postpischil在我发布的代码中正确地开了一个洞;它检查每个位是否出现在三个参数中的最多一个中。不幸的是,我想不出一个解决问题的好方法。

浮点绝对值可以(忽略NaN)通过屏蔽掉符号位来实现,因此您可以使用它。此外,像==这样的比较可以编译为条件移动而不是粗略的移动。