【发布时间】:2010-12-06 14:45:44
【问题描述】:
为什么 NaN 值的比较与所有其他值的行为不同? 也就是说,所有与运算符 ==、=、 的比较(其中一个或两个值为 NaN)都返回 false,这与所有其他值的行为相反。
我想这在某种程度上简化了数值计算,但我找不到明确说明的原因,甚至在 Kahan 的 Lecture Notes on the Status of IEEE 754 中也没有,它详细讨论了其他设计决策。
这种异常行为在进行简单的数据处理时会造成麻烦。例如,当对记录列表进行排序时。 C 程序中的一些实值字段我需要编写额外的代码来处理 NaN 作为最大元素,否则排序算法可能会变得混乱。
编辑: 到目前为止的答案都认为比较 NaN 是没有意义的。
我同意,但这并不意味着正确答案是错误的, 而是一个非布尔值 (NaB),幸运的是它不存在。
因此,在我看来,比较返回 true 或 false 的选择是任意的, 对于一般数据处理,如果它遵守通常的法律将是有利的 (== 的自反性, 的三分法), 以免依赖这些定律的数据结构变得混乱。
所以我要求打破这些法律的一些具体优势,而不仅仅是哲学推理。
编辑 2: 我想我现在明白为什么将 NaN 设为最大值是个坏主意,它会弄乱上限的计算。
NaN != NaN 可能是可取的,以避免检测循环中的收敛,例如
while (x != oldX) {
oldX = x;
x = better_approximation(x);
}
然而,最好通过将绝对差异与小限制进行比较来编写。 所以恕我直言,这是在 NaN 打破反身性的一个相对较弱的论据。
【问题讨论】:
-
一旦 NaN 进入计算,它通常永远不会离开,因此您的收敛测试将成为无限循环。通常最好将收敛失败报告给调用例程,可能通过返回 NaN。因此,循环结构通常会变成类似
while (fabs(x - oldX) > threshold)的东西,如果收敛发生或 NaN 进入计算,则退出循环。然后将在循环外检测 NaN 和适当的补救措施。 -
如果 NaN 是 while 循环仍然有效的顺序的最小元素。
标签: floating-point comparison nan ieee-754 iec10967