这是What is the rationale for all comparisons returning false for IEEE754 NaN values?的后续问题(我认为这是另一个问题而不是评论更好)。它有一个非常好的答案,正好缺少一个重要的事情:为什么NaN != NaN
?
我知道NaN与数字相比是无序的,因此NaN < x
和NaN > x
都是假的。但这并不能解释为什么平等是倒退的。引用我链接到的问题的答案:
有必要为程序员提供一种方便有效的方法来检测NaN值,这些值并不依赖于提供类似
之类的编程语言isNan()
好的:
if((0/0) == x) print "I found NaN!";
//using 0/0 is more readable than using 0x7fc00000 or 0x7ff8000000000000
方便,高效,并且不依赖于编程语言提供的构造。即使编程语言没有定义全局NaN,您也可以自己轻松地创建一个本地(或全局)变量。
单个额外操作肯定效率不高,尤其是因为FPU具有硬编码响应(无需计算)。使用0/0也比不合逻辑的x!=x
更方便程序员。
程序很少需要检查NaN,并且每次检查只有一个额外的操作不会是程序效率低下的原因。同样地,没有任何程序如此克制,以至于它无法处理单个额外变量,尤其是临时变量。
对我来说,论证&#34;我需要NaN!=NaN
以便我可以检测到它#34;没有意义:它和&#34完全相同的论点;我需要Infinity!=Infinity
以便我能够检测到它#34;。不,你不要像其他人一样将它与1/0进行比较。
所以我的问题比原来的问题要窄得多:为什么NaN != NaN
?
我之前无法确定是否曾经问过这个问题,因为原始问题有很多重复。
旁注:
NaN == NaN
现在不会改变
虽然FPU现在没有改变,但是一些编程语言已经改变,因此NaN == NaN
是真的。
修改
让我试着澄清为什么到目前为止我还没有接受任何答案。到目前为止,我已经阅读了这些评论,对不起,我已经放弃了球:而不是解释为什么我不同意我刚刚问过&#34;为什么&#34;希望你给出不同的理由。所以让我试着更好地解释一下我的观点。
Infinity和NaN在很多方面都很相似。
x == Infinity
不使用数字相等(因为Infinity不是数字)而是检查x是否代表正无穷大的概念。如果x是&#34;而不是数字&#34;的概念,我同样期望从x == NaN
完全相同的东西返回true。但事实并非如此(至于为什么这个问题的重点)。x == (1/0)
是将x与无穷大进行比较的方法。x-1
不会改变无穷大或NaN的值。所以是的,当你说过时,我确实听到了你的声音,而且平等没有意义,因为它不是一个数字&#34;但是我不同意这种说法,因为如果它是真的那么按照#1来比较无限(也不是一个数字)也没有意义。虽然根据#2,比较非数字是有意义的。
我实际上已经阅读了原始问题的每个答案(以及Why are floating point infinities, unlike NaNs, equal?,其中有一些相关的答案)。所有关于NaN != NaN
为什么的论证都归结为&#34;因为它不是一个数字&#34; (已经解决)或&#34;因为有许多不同的位表示&#34;被#5反击。
我无法想出为什么NaN应该有不同的平等。我并不是说我占了一切:所以我错过了什么?我的一个论点是错的还是还有其他一些我没想到的原因?这就是为什么我一直在露营这个词的原因&#34;为什么&#34;。如果你不同意,那么反驳我或捍卫你的观点。我猜测我的上述逻辑至少会有一个反对点,我期待听到它。
我再次为在原始问题中不包括这些而道歉,因为我一直在考虑它们。我很抱歉这可能会对现有答案产生重大影响。
答案 0 :(得分:3)
有几种方法可以生成NaN
。
想象一下:
double expr1 = 0.0 / 0.0;
double expr2 = Math.log(-1.0);
if (expr1 == expr2) {
// They are the same
}
这两个NaN
,如果它们可以表示为数字,则很有可能成为不同的值。
如果NaN == NaN
成立,则此代码段会产生意外结果,将它们视为相等。由于大多数程序都根据预期进行比较(因此他们使用==
,<=
,而不是!==
,!<=
),返回false
不会不要让这些程序结束错误的事情。