In C, is testing if a float is NaN as fast as testing if two floats are equal? That is is isnan()
as fast a simple equality test between two floats?
My particular interest is using gcc
on a standard modern Intel/AMD platform.
Here is a sample piece of C code.
#include <math.h>
int main(double x)
{
return isnan(x);
}
Using GCC on x64, math.h
's isnan(float)
compiles to
jmp __isnanf
Using tail-call optimization, but effectively calling a function. The called function will have to do something equivalent to the code a bit down, at least I don't see any faster way to implement it. That leaves the question how it compares to a comparison unanswered however.
But that doesn't say anything about how fast "testing if a float is NaN" is, because there isn't just the one way to do it. The most direct way,
int isnan2(float x)
{
return x != x;
}
Is literally the same thing as comparing floats at the C level. But GCC makes this:
xor eax, eax
ucomiss xmm0, xmm0
setp al
ret
Which is not quite the same thing as comparing two floats, but close, and in fact a bit faster. Testing for equality means the unordered case tested, as it is here, but then the z flag also has to be tested, like this (from gcc again)
xor eax, eax
mov edx, 1
ucomiss xmm0, xmm1
setp al
cmovne eax, edx
ret
Bonus: using <cmath>
makes isnan
compile to the same thing as comparing a float to itself, see the linked question for why.
I now see you actually had double
, but that doesn't change anything qualitatively.