Checking if a double (or float) is NaN in C++
According to the IEEE standard, NaN values have the odd property that comparisons involving them are always false. That is, for a float f, f != f
will be true only if f is NaN.
Note that, as some comments below have pointed out, not all compilers respect this when optimizing code.
For any compiler which claims to use IEEE floating point, this trick should work. But I can't guarantee that it will work in practice. Check with your compiler, if in doubt.
There is no isnan()
function available in current C++ Standard Library. It was introduced in C99 and defined as a macro not a function. Elements of standard library defined by C99 are not part of current C++ standard ISO/IEC 14882:1998 neither its update ISO/IEC 14882:2003.
In 2005 Technical Report 1 was proposed. The TR1 brings compatibility with C99 to C++. In spite of the fact it has never been officially adopted to become C++ standard, many (GCC 4.0+ or Visual C++ 9.0+ C++ implementations do provide TR1 features, all of them or only some (Visual C++ 9.0 does not provide C99 math functions).
If TR1 is available, then cmath
includes C99 elements like isnan()
, isfinite()
, etc. but they are defined as functions, not macros, usually in std::tr1::
namespace, though many implementations (i.e. GCC 4+ on Linux or in XCode on Mac OS X 10.5+) inject them directly to std::
, so std::isnan
is well defined.
Moreover, some implementations of C++ still make C99 isnan()
macro available for C++ (included through cmath
or math.h
), what may cause more confusions and developers may assume it's a standard behaviour.
A note about Viusal C++, as mentioned above, it does not provide std::isnan
neither std::tr1::isnan
, but it provides an extension function defined as _isnan()
which has been available since Visual C++ 6.0
On XCode, there is even more fun. As mentioned, GCC 4+ defines std::isnan
. For older versions of compiler and library form XCode, it seems (here is relevant discussion), haven't had chance to check myself) two functions are defined, __inline_isnand()
on Intel and __isnand()
on Power PC.