`isnan()`和测试平等一样快吗?

时间:2015-11-25 16:50:33

标签: c optimization nan

在C中,测试浮点数是否与测试两个浮点数相等的NaN一样快?那是isnan()和两个浮点数之间的简单相等测试一样快吗?

我特别感兴趣的是在标准的现代英特尔/ AMD平台上使用gcc

这是一段C代码示例。

#include <math.h>
int main(double x)
{
  return isnan(x);
}

3 个答案:

答案 0 :(得分:3)

在x64上使用GCC,math.h&#39; s isnan(float)编译为

jmp __isnanf

使用尾调用优化,但有效地调用函数。被调用的函数必须做一些与代码相当的东西,至少我没有看到任何更快的实现方法。这留下了一个问题,它与未答复的比较相比如何。

但这并没有说明如何快速测试浮子是否为NaN&#34;是的,因为没有一种方法可以做到这一点。最直接的方式,

int isnan2(float x)
{
  return x != x;
}

与C级别的浮动比较完全相同。但是海湾合作委员会做了这个:

xor eax, eax
ucomiss xmm0, xmm0
setp    al
ret

这与相同的事情不如比较两个浮点数,但接近,实际上更快一点。测试相等意味着测试的无序情况,就像在这里一样,但是z标志也必须进行测试,如此(再次来自gcc)

xor eax, eax
mov edx, 1
ucomiss xmm0, xmm1
setp    al
cmovne  eax, edx
ret

奖励:使用<cmath>使isnan编译与将浮点数与自身进行比较相同,请参阅链接问题。

Godbolt link for convenience

我现在看到你实际上有double,但这并没有定性地改变任何内容。

答案 1 :(得分:1)

  

问题是我们是否应该在代码中使用除NaN之外的其他内容来表示未知值。 (OP comment

然后您应该将isnan(x)x == some_constant进行比较。如果some_constant没有值0或NAN,那么如果使用典型的FP表示,比较可能只是一点比较 - 很难在速度上击败它。

尽管如此,NaN还是更惯用的。

答案 2 :(得分:0)

没有。相等性测试是内联的,因此您需要支付调用isnan()的函数调用开销的代价。但是平等不能用于IEEE,所以......