23

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:

The comparisons EQ, GT, GE, LT, and LE, when either or both operands is NaN returns FALSE.

The comparison NE, when either or both operands is NaN returns TRUE.

Are the above rules enforced in C/C++?

user2188453
  • 1,105
  • 1
  • 12
  • 26

2 Answers2

17

The == and != operators appear to not be constrained to the IEEE 754 behavior for NaNs, 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 NaNs 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, and equal - is true. Relational operators may raise the "invalid" floating-point exception when argument values are NaNs. For a NaN and a numeric value, or for two NaNs, 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.

dxiv
  • 16,984
  • 2
  • 27
  • 49
13

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.

SirGuy
  • 10,660
  • 2
  • 36
  • 66
AlexD
  • 32,156
  • 3
  • 71
  • 65
  • 2
    This is a bit misleading. The question does not ask about IEC 559 in general, it asks about one specific aspect of that standard, which may or may not be guaranteed by the C and C++ standards directly even on implementations that disregard IEC 559. –  Aug 05 '16 at 23:08
  • 1
    The standard says that "Two values (other than NaNs) with the same object representation compare equal" though. – a3f Aug 05 '16 at 23:18
  • @a3f Yes, but that by itself leaves unspecified whether two NaNs with the same object representation also compare equal. –  Aug 05 '16 at 23:22
  • 1
    @hvd I think the point is that if it disregards IEC559, the standard doesn't specify any requirements -- they may or may not compare equal. You can only depend on the results if it supports IEC559. – Barmar Aug 05 '16 at 23:23
  • @hvd Agreed, reworded a bit. – AlexD Aug 05 '16 at 23:23
  • 1
    I think there is one requirement on NaNs when an implementation does not follow IEC 559, at least in C: 6.5.9 Equality operators (`==` and `!=`): "For any pair of operands, exactly one of the relations is true." This disallows implementations from treating NaNs similarly to SQL NULLs which compare neither equal nor unequal to themselves. –  Aug 05 '16 at 23:32
  • @hvd Good point. FWIW the `C++` standard conspicuously omits the `For any pair of operands, exactly one of the relations is true` part at 5.10 *Equality operators*. – dxiv Aug 06 '16 at 00:17