尽管不合逻辑,754决定NaN!= NaN?
这是一个后续问题什么是IEEE754 NaN值返回false的所有比较的基本原理是什么? (我认为这是另一个问题,而不是评论)。 它有一个非常好的答案,它完全错过了一件重要的事情:为什么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,并且每次检查一次额外的操作不会成为程序效率低下的原因。 同样,没有任何程序如此受限制,无法处理一个额外的变量,特别是临时变量。
对我来说,“我需要NaN!=NaN
以便我可以检测到”的说法没有任何意义:这与“我需要Infinity!=Infinity
以便我可以检测到它”完全相同。 不,你不这样做,就像其他人一样把它比作1/0。
所以我的问题比原来的问题要窄得多:为什么NaN != NaN
?
由于原始问题存在大量重复,因此我无法确定这是否曾被问过。
边注:
NaN == NaN
现在不会改变
而FPU现在不会改变,一些编程语言已经改变了,所以NaN == NaN
是真的。
编辑:
让我试着澄清为什么到目前为止我还没有接受任何答案。 到目前为止,我已经阅读了评论,我很抱歉,我已经放弃了球:不是解释为什么我不同意,我只是问“为什么”希望你给出一个不同的理由。 所以让我试着更好地解释我的观点。
Infinity和NaN在很多方面都很相似。
x == Infinity
不使用数字相等(因为Infinity不是数字),而是检查x是否表示正无穷的概念。 如果x是“不是数字”的概念,但是情况并非如此(至于为什么是这个问题的要点),我还希望从x == NaN
完全相同的事情返回true。 x == (1/0)
就是比较x和无穷大的方法。 x-1
不会改变Infinity或NaN的值)。 所以是的,当你说“平等没有意义,因为它不是一个数字”时,我听到了你的声音,但我不同意这种说法,因为如果它是真的,那么根据#1,它也没有意义比较Infinity (这也不是一个数字)。 虽然按照#2,但比较非数字是有意义的。
事实上,我已经阅读了关于原始问题的每一个答案(以及为什么浮点数无关,与NaN不同,它有相同的答案)。 所有关于为什么NaN != NaN
的论点都归结为“因为它不是数字”(已经解决)或者“因为存在许多不同的位表示”,所以它们被#5反驳。
我想不出为什么NaN应该有不同的平等。 我并不是说我已经解释了一切:所以我错过了什么? 我的一个观点是错误的还是有其他原因,我没有想到? 这就是为什么我一直在“为什么”这个词露宿。 如果您不同意,请反驳我或捍卫您的观点。 我猜测我的上述逻辑至少会有一个反面,我期待着听到它。
自从我一直在考虑这些问题之后,我再次对原始问题中的这些问题表示歉意。 我也很抱歉,这可能会导致现有答案发生重大变化。
有几种生产NaN
。
想象一下:
double expr1 = 0.0 / 0.0;
double expr2 = Math.log(-1.0);
if (expr1 == expr2) {
// They are the same
}
如果这两个NaN
可以表示为数字,那么这两个NaN
将很有可能是不同的值。
如果NaN == NaN
将持有,则此片段将具有将它们等同比较的意外结果。 由于大多数程序根据他们的期望进行比较(因此他们使用==
, <=
,但不是!==
!<=
),返回false
并不会使这些程序得出错误的结论。
上一篇: 754 decide NaN != NaN despite being illogical?
下一篇: SIMD instructions for floating point equality comparison (with NaN == NaN)