我最初的回答(从 4 年前开始)从现代的角度批评了这个决定,而不了解做出决定的背景。因此,它没有回答这个问题。
正确答案在这里给出:
NaN
!=NaN
源于两个务实的考虑:
isnan( )
[...] NaN 在 8087 算术中形式化时没有谓词;有必要为程序员提供一种方便有效的检测 NaN 值的方法,这种方法不依赖于isnan( )
可能需要很多年的编程语言
这种方法有一个缺点:它使 NaN 在许多与数值计算无关的情况下不太有用。例如,很久以后,当人们想用它NaN
来表示缺失值并将它们放入基于散列的容器中时,他们就做不到了。
如果委员会预见到未来的用例,并认为它们足够重要,那么他们可能会选择更冗长的,!(x<x & x>x)
而不是x!=x
作为NaN
. 然而,他们的关注点更加务实和狭隘:为数值计算提供最佳解决方案,因此他们认为他们的方法没有问题。
===
原答案:
很抱歉,尽管我很欣赏票数最高的答案中的想法,但我不同意。NaN 并不意味着“未定义” - 请参阅http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF第 7 页(搜索“未定义”一词)。正如该文件所证实的,NaN 是一个定义明确的概念。
此外,IEEE 的方法是尽可能遵循常规数学规则,如果不能,则遵循“最小意外”规则 - 参见https://stackoverflow.com/a/1573715/336527。任何数学对象都等于它自己,所以数学规则意味着 NaN == NaN 应该是 True。我看不出有任何有效和有力的理由来偏离这样一个主要的数学原理(更不用说不太重要的比较三分法规则等)。
结果,我的结论如下。
IEEE 委员会成员对此并没有想得很清楚,并且犯了一个错误。由于很少有人了解 IEEE 委员会的方法,或者关心标准对 NaN 的确切说明(也就是说:大多数编译器对 NaN 的处理无论如何都违反了 IEEE 标准),所以没有人发出警报。因此,这个错误现在嵌入到标准中。它不太可能被修复,因为这样的修复会破坏很多现有代码。
编辑:这是一个非常有用的讨论的帖子。注意:要获得公正的观点,您必须阅读整个线程,因为 Guido 与其他一些核心开发人员的观点不同。然而,Guido 个人对这个话题并不感兴趣,并且在很大程度上遵循了 Tim Peters 的建议。如果有人支持 Tim Peters 的论点NaN != NaN
,请在评论中添加它们;他们很有机会改变我的看法。