Doing some optimziation on a piece of code, the correctness of the code depending on how the compiler handle NaNs.
I read the IEEE-754 rules on NaN, which states:
C/C++ does not require specific floating-point representation and does not require that any comparison against NaN
is false
.
In C++ you can check if all floating-point types fulfill IEEE 754 using std::numeric_limits::is_iec559
:
static constexpr bool is_iec559;
56 True if and only if the type adheres to IEC 559 standard.217
57 Meaningful for all floating point types.
217) International Electrotechnical Commission standard 559 is the same as IEEE 754.
For other floating-point representations comparison against NaN
may or may not behave the same way.
In fact, even representing NaN
itself is not required. See std::numeric_limits<T>::has_quiet_NaN,
std::numeric_limits<T>::has_signaling_NaN.
The ==
and !=
operators appear to not be constrained to the IEEE 754
behavior for NaN
s, as pointed out in @AlexD's answer already.
However, the <math.h>
comparison macros are required to follow NaN
rules equivalent to IEEE 754
's. The following from the C11
draft N1580 under 7.12.14 Comparison Macros states that the <math.h>
comparison macros are required to ensure that, if either or both of x, y
are NaN
s then:
isunordered(x, y)
is true
isgreater(x, y)
, isgreaterequal(x, y)
, isless(x, y)
, islessequal(x, y)
are all false
The relational and equality operators support the usual mathematical relationships between numeric values. For any ordered pair of numeric values exactly one of the relationships -
less
,greater
, andequal
- is true. Relational operators may raise the "invalid" floating-point exception when argument values areNaN
s. For aNaN
and a numeric value, or for twoNaN
s, just the unordered relationship is true.
The C++
standard simply defers to the C
one on <math.h>
matters:
The classification/comparison functions behave the same as the C macros with the corresponding names defined in 7.12.3, Classification macros, and 7.12.14, Comparison macros in the C Standard.