Floating point 为什么IEEE-754决定NaN!=NaN尽管不合逻辑?

Floating point 为什么IEEE-754决定NaN!=NaN尽管不合逻辑?,floating-point,comparison,nan,ieee-754,iec10967,Floating Point,Comparison,Nan,Ieee 754,Iec10967,这是一个后续问题(我认为作为另一个问题比评论更好)。它有一个非常好的答案,但却恰恰遗漏了一件重要的事情:为什么NaN!=南 我知道NaN与数字相比是无序的,因此NaNx都是错误的。但这并不能解释为什么平等是倒退的。引用我链接到的问题的答案: 有必要为程序员提供一种方便、高效的方法来检测NaN值,这种方法不依赖于编程语言提供类似于isNan() 好的,那么: if((0/0) == x) print "I found NaN!"; //using 0/0 is more readable than

这是一个后续问题(我认为作为另一个问题比评论更好)。它有一个非常好的答案,但却恰恰遗漏了一件重要的事情:为什么
NaN!=南

我知道NaN与数字相比是无序的,因此
NaN
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
现在不会改变

虽然FPU现在不会更改,但一些编程语言已经更改,因此
NaN==NaN
是正确的

编辑:

让我试着澄清一下为什么到目前为止我还没有接受任何答案。到目前为止,我已经阅读了这些评论,很抱歉我失手了:我没有解释为什么我不同意,而是问了“为什么”,希望你能给出一个不同的理由。所以让我试着更好地解释我的观点

Infinity和NaN在许多方面相似

  • 无限和NaN都是概念。无限不是一个数字,而是一个永无止境的概念。如果x是无穷大,那么它表示x是无穷大的。NaN不是一个数字(duh),代表一个无效状态或数学上无效的东西。对于数学完整性:然而,无穷大是浮点数近似实数(尽管它们更接近有理数),而无穷大肯定不在实数中。因此,就FPU和实数线而言,无限(所有类型)不是一个数字(根据域的“数字”定义)
  • 相等并不总是数字相等。如果两个操作数都是数字(而不是概念),即使要求FPU执行比较,一般相等也只是数字相等。当一个操作数为无穷大或NaN时,使用一般相等,以查看另一个操作数是否表示相同的概念。例如,
    x==Infinity
    不使用数字相等(因为Infinity不是数字),而是检查x是否表示正无穷大的概念。同样地,如果x是“不是数字”的概念,那么我也希望从
    x==NaN
    得到完全相同的结果,但事实并非如此(至于这个问题的重点是什么)
  • 两者都可以通过除以0来检索:0/0返回NaN,1/0返回无穷大。如果你的语言没有无穷大的常数,那么
    x==(1/0)
    是比较x和无穷大的方法
  • 多种口味。无限有无限多种类型(因为基数)。然而,FPU没有做出任何区别:无限是一个通用的,也是唯一可用的。有了这些构造,就不可能问x是否是可数无穷大。NaN在概念上只有一种类型(“不是数字”),但它有两种处理方式:静默和信令。我对信号传递一无所知,但根据我的理解,如果你试着比较一个信号传递的等式,它会抛出,因此,因为它没有等式,所以它不完全是关于主题的
  • 位表示法。NaN有许多不同的位表示,但Infinity只有1(1表示-Infinity)。然而,NaN的所有表示在逻辑上都是完全相同的值,因为它们都表示“不是数字”的相同概念。0x7FF80000000000和0x7FF800000000001之间没有区别:它们的意思完全相同,并且允许使用完全相同的数学返回任一结果。您不能询问x是sqrt(-1)还是log(-1),因为这两个值返回的值完全相同:NaN。类似于只有一种无限,只有一种(安静的)NaN。是的,有多个位表示,但其中一个并不比其他位表示大:FPU使用特殊逻辑来完全相同地处理它们。这同样适用于-0,它的位与+0不同,但处理方式完全相同。因此,位是与逻辑相等无关的实现细节
  • (与主题无关,但它们都有特殊的数学:
    x-1
    不会更改无穷大或NaN的值)
  • 所以是的,我确实听到你说“平等没有意义,因为它不是一个数字”,但我不同意这种说法,因为如果它是真的,那么根据#1,比较无穷大(它也不是一个数字)也没有意义。尽管根据#2,比较非数字是有意义的

    事实上,我已经阅读了原问题的所有答案
    double expr1 = 0.0 / 0.0;
    double expr2 = Math.log(-1.0);
    if (expr1 == expr2) {
      // They are the same
    }