尽管不合逻辑,754决定NaN!= NaN?

这是一个后续问题什么是IEEE754 NaN值返回false的所有比较的基本原理是什么? (我认为这是另一个问题,而不是评论)。 它有一个非常好的答案,它完全错过了一件重要的事情:为什么NaN != NaN

我知道NaN与数字相比是无序的,因此NaN < xNaN > 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在很多方面都很相似。

  • Infinity和NaN都是概念。 Infinity不是一个数字,它是一个永无止境的概念。 如果x是无穷大,那么它表示x是无穷无尽的。 NaN不是一个数字(duh),并且代表一个无效的状态或某种非数学有效的东西。 对于数学完整性来说:无穷大是一个“数字”,然而浮点数接近实数(尽管它们更接近有理数),而无穷大确实不在实数中。 因此,就FPU和实数行而言,无穷大(所有类型)不是数字(按照域的“数字”定义)。
  • 平等并不总是数字平等。 即使FPU被要求执行比较,如果两个操作数都是数字(而不是概念),则通用平等只是数字相等。 当一个操作数是Infinity或NaN以便查看另一个操作数是否代表相同的概念时,使用通用平等。 例如x == Infinity不使用数字相等(因为Infinity不是数字),而是检查x是否表示正无穷的概念。 如果x是“不是数字”的概念,但是情况并非如此(至于为什么是这个问题的要点),我还希望从x == NaN完全相同的事情返回true。
  • 两者都可以通过除以0得到:0/0返回NaN,1/0返回无穷大。 如果你的语言对Infinity没有常数,那么x == (1/0)就是比较x和无穷大的方法。
  • 多种口味。 Infinity有无穷多种类型(因为基数)。 然而FPU没有做出任何区分:Infinity是一个通用目标,也是唯一可用的目标。 有了这些构造,就不可能问例如x是否可数无穷。 NaN在概念上只有一种类型(“不是数字”),但它有两种处理方式:安静和信令。 我对信号一无所知,但从我的理解来看,如果您试图比较它会抛出的信号NaN的相等性,因为它不具有平等性,所以它不完全是主题。
  • 位表示。 NaN有许多不同的位表示,但Infinity只有1个(对于-Infinity为1)。 然而,NaN的所有表示在逻辑上都完全相同,因为它们都表示“不是数字”的相同概念。 在0x7FF8000000000000和0x7FF8000000000001之间没有区别:它们意味着完全相同的东西,并且允许完全相同的数学运算返回任一结果。 你不能问x是sqrt(-1)还是x是log(-1),因为这两者会返回完全相同的结果:NaN。 类似于只有一种Infinity,只有一种(安静)NaN。 是的,有多个位表示,但其中一个不会大于其他表示:FPU使用特殊逻辑来处理它们完全相同。 这对于-0具有与+0不同的位但同样处理完全相同。 因此这些位是与逻辑相等无关的实现细节。
  • (离题,但他们都有特殊的数学: 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并不会使这些程序得出错误的结论。

    链接地址: http://www.djcxy.com/p/58503.html

    上一篇: 754 decide NaN != NaN despite being illogical?

    下一篇: SIMD instructions for floating point equality comparison (with NaN == NaN)