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

NaN comparison rule in C/C++

本文关键字:NaN 比较规则 中的 C++      更新时间:2023-10-16

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

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

当任一操作数或两个操作数同时存在时,比较EQ、GT、GE、LT和LEis NaN返回FALSE。

当其中一个或两个操作数都为NaN时,比较NE返回TRUE。

以上规则在C/C++中执行了吗?

==!=运算符似乎被约束为NaNs的IEEE 754行为,正如@AlexD的回答中已经指出的那样。

但是,<math.h>比较宏需要遵循相当于IEEE 754NaN规则。C11草案N1580根据7.12.14比较宏规定,需要<math.h>比较宏来确保,如果x, y中的一个或两个都是NaN,则:

  • isunordered(x, y)true

  • isgreater(x, y)isgreaterequal(x, y)isless(x, y)islessequal(x, y)均为false

关系运算符和等式运算符支持数值之间的常见数学关系。对于任何有序数值对,关系式lessgreaterequal中的一个恰好为真。当参数值为NaN s时,关系运算符可能引发"无效"浮点异常。对于一个NaN和一个数值,或者对于两个NaN s,只有无序关系为true

C++标准在<math.h>问题上简单地服从于C标准:

分类/比较函数的行为与具有相应名称的C宏相同定义见7.12.3"分类宏"和7.12.14"C标准中的比较宏"。

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

在C++中,您可以使用std::numeric_limits::is_iec559:检查所有浮点类型是否符合IEEE 754

static constexpr bool is_iec559;

56当且仅当类型符合IEC 559标准时为真217

57对所有浮点类型都有意义。


217(国际电工委员会标准559与IEEE 754相同。

对于其他浮点表示法,与NaN进行比较行为可能相同,也可能不同。

事实上,甚至不需要表示NaN本身。参见CCD_ 34,CCD_ 35。