2

Is there a clever expression trick to test if a float vec3 is axial (i.e. two zero components) without using multiple equality tests?

At first I thought of if(abs(x)+abs(y)==0.0) (pseudocode)... but of course each abs call probably does a branch/equality test.

I thought of masking each float's bytes together and testing the result, but IEEE FP has both positive and negative 0.

4

2 回答 2

3

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

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

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

在评估“所有位”标准之前,没有任何位运算可以帮助评估。任何失去相同值中位之间关系的按位运算都是无用的。本质上,您需要分别了解上述各项但上述每一项都相当于与零进行浮点比较。

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

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

于 2013-04-19T13:30:47.670 回答
-1

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

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

于 2013-04-18T23:09:18.927 回答