C/C++中的NaN比较规则

NaN comparison rule in C/C++

对一段代码做一些优化,代码的正确性取决于编译器如何处理 NaN。

我阅读了关于 NaN 的 IEEE-754 规则,其中指出:

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.

以上规则是否在 C/C++ 中执行?

C/C++ 不需要特定的浮点表示,也不需要与 NaN 的任何比较是 false.

在 C++ 中,您可以使用 std::numeric_limits::is_iec559:

检查是否所有浮点类型都满足 IEEE 754

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.

对于其他浮点表示与 NaN 的比较 行为方式可能相同也可能不同。

其实连代表NaN本身都不需要。参见std::numeric_limits<T>::has_quiet_NaNstd::numeric_limits<T>::has_signaling_NaN.

==!= 运算符似乎 受限于 NaNIEEE 754 行为,因为已经在@AlexD 的回答中指出了。

但是,<math.h> 比较宏 需要 遵循等同于 IEEE 754NaN 规则。以下来自 7.12.14 比较宏 下的 C11 草案 N1580 指出 <math.h> 比较宏 所必需的确保,如果 x, y 中的一个或两个都是 NaN,则:

  • isunordered(x, y)true

  • isgreater(x, y)isgreaterequal(x, y)isless(x, y)islessequal(x, y)都是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.

C++ 标准只是在 <math.h> 事项上服从 C 标准:

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.