Reputation: 30118
Although Microsoft blogs claim otherwise using std::isnan
in my code still does generate calls to c++ runtime instead of inlined ucomiss
.
Now I worked around that with x!=x
check(since perf matters to me in this piece of code), but that made me wonder... If x!=x
is a way to check for NaNess would that not be an easy way to implement std::isnan
?
But from what I know gcc/clang use intrinsics (and msvc is trying). Why would they bother if it can be efficiently implemented as a normal function?
So I am a bit confused since one of the answers on SO claims that it is the only way selfcomparison can return false.
Upvotes: 4
Views: 273
Reputation: 724
std::isnan(x)
and (x != x)
are not really equivalent.
The original questions asks in C++ but the answer applies to C as well.
ISO/IEC TS 18661-1 (which is incorporated into the upcoming C23 standard) clarified the behavior of isnan()
that the function never throws any exception, even when the argument is a signaling NaN.
The (x != x)
expression, on the other hand, does throw "Invalid Operation" exception (FE_INVALID) when x
is a signaling NaN.
The differences are on signaling NaNs only, and so GCC would optimize std::isnan(x)
to (x != x)
when signaling NaN support is off (-fno-signaling-nans
, which is the default).
This Stack Overflow question is related: Is `isnan()` as fast as testing equality?
Upvotes: 1
Reputation: 234795
The C++ standards committee (finally?) listened to the numericists on this one. Prior to C++11, the idiom
x != x
was indeed used to check for NaN-ness. There is no other class of values of a floating point number for which the idiom applies. But it never sat particularly well. For starters, some NaNs can raise exceptions. It's also vulnerable to errant refactoring. You could also be assuming some floating point standard, such as the commonplace IEEE754.
From C++11 onwards using std::isnan
is much preferred.
Upvotes: 5