为什么NaN值的比较与所有其他值的比较行为不同? 也就是说,与运算符==,<=,>=,<,>的所有比较,其中一个或两个值都是NaN,返回false,与所有其他值的行为相反。

我认为这在某种程度上简化了数值计算,但我找不到一个明确的原因,甚至在Kahan的《IEEE 754状态讲义》中也找不到,他详细讨论了其他设计决策。

在进行简单的数据处理时,这种异常行为会造成麻烦。例如,当在C程序中对记录列表w.r.t.某个实值字段进行排序时,我需要编写额外的代码来处理NaN作为最大元素,否则排序算法可能会变得混乱。

编辑: 到目前为止,所有的答案都认为比较nan是没有意义的。

我同意,但这并不意味着正确答案是错误的, 而是一个非布尔型(NaB),幸运的是它并不存在。

所以在我看来,选择返回真或假进行比较是随意的, 对于一般的数据处理来说,如果它符合通常的规律,那将是有利的 (==的反身性,<,==,>的三分), 以免依赖这些定律的数据结构变得混乱。

所以我要求的是打破这些定律的一些具体好处,而不仅仅是哲学推理。

编辑2: 我想我现在明白为什么让NaN最大是一个坏主意了,它会搞砸上限的计算。

NaN != NaN可能是可取的,以避免检测循环中的收敛,例如

while (x != oldX) {
    oldX = x;
    x = better_approximation(x);
}

但是最好是通过比较小极限下的绝对差来写。 所以恕我直言,这是一个相对较弱的论点,打破自反性在NaN。


当前回答

很简单的回答:

因为以下几点: Nan / Nan = 1 绝对不能持有。否则inf/inf等于1。

(因此nan不能等于nan。对于>或<,如果nan尊重满足阿基米德性质的集合中的任何顺序关系,我们将再次得到nan / nan = 1的极限)。

其他回答

While I agree that comparisons of NaN with any real number should be unordered, I think there is just cause for comparing NaN with itself. How, for example does one discover the difference between signaling NaNs and quiet NaNs? If we think of the signals as a set of Boolean values (i.e. a bit-vector) one might well ask whether the bit-vectors are the same or different and order the sets accordingly. For example, on decoding a maximum biased exponent, if the significand were left shifted so as to align the most significant bit of the significand on the most significant bit of the binary format, a negative value would be a quiet NaN and any positive value would be a signaling NaN. Zero of course is reserved for infinity and the comparison would be unordered. MSB alignment would allow for the direct comparison of signals even from different binary formats. Two NaNs with the same set of signals would therefore be equivalent and give meaning to equality.

我不知道其设计原理,但以下是IEEE 754-1985标准的摘录:

应该能够比较所有支持格式的浮点数,即使操作数的格式不同。比较是精确的,不会溢出也不会溢出。可能存在四种互斥关系:小于、等于、大于和无序。当至少有一个操作数是NaN时,会出现最后一种情况。每个NaN都应该与一切事物,包括它自己,进行无序比较。”

过于简单的回答是,NaN没有数值,因此其中没有任何东西可以与其他任何东西进行比较。

如果您希望nan像+INF一样工作,您可以考虑测试并使用+INF替换nan。

因为数学是数字“仅仅存在”的领域。 在计算中,你必须初始化这些数字,并根据需要保持它们的状态。 在过去的日子里,内存初始化的工作方式是你永远无法依赖的。你永远不能允许自己这样想“哦,它会一直用0xCD初始化,我的算法不会坏”。

所以你需要合适的非混合溶剂,足够粘稠,不会让你的算法被卷入和破坏。 涉及数字的优秀算法大多使用关系,而那些if()关系将被省略。

这只是油脂,你可以在创建新变量,而不是从计算机内存编程随机地狱。不管你的算法是什么,都不会崩溃。

接下来,当您仍然突然发现您的算法正在生成nan时,可以将其清除,一次查看每个分支。同样,“总是错误”的规则在这方面很有帮助。

我猜NaN(不是一个数字)的意思就是:这不是一个数字,因此比较它是没有意义的。

这有点像SQL中带有空操作数的算术:它们的结果都为空。

浮点数的比较比较数值。因此,它们不能用于非数值值。因此,NaN不能在数字意义上进行比较。