C IEEE-Floats inf等于inf

时间:2017-01-24 17:31:23

标签: c floating-point ieee-754

在C中,在使用IEEE-754浮点数的实现中,当我比较两个NaN的浮点数时,它返回0或" false"。但是为什么两个浮点数都被认为是相等的呢?

本程序打印等于:..." (至少在使用gcc的Linux AMD64下)并且在我看来它应该打印不同的:......"。

#include <stdio.h>
#include <stdlib.h>

int main(void)
  {
    volatile double a = 1e200; //use volatile to suppress compiler warnings
    volatile double b = 3e200;
    volatile double c = 1e200;
    double resA = a * c;  //resA and resB should by inf
    double resB = b * c;
    if (resA == resB)
      {   
        printf("equal: %e * %e = %e = %e = %e * %e\n",a,c,resA,resB,b,c);
      }   
    else
      {   
        printf("different: %e * %e = %e != %e = %e * %e\n", a, c, resA, resB, b, c);
      }   
    return EXIT_SUCCESS;
  }

另一个例子,为什么我认为inf与inf不同,是:自然数和有理数的数字,都是无限的但不一样。

那么为什么inf == inf?

4 个答案:

答案 0 :(得分:5)

无限比较相等,因为这就是标准所说的。来自 5.11部分比较谓词的详细信息:

  

相同符号的无限操作数应比较相等。

答案 1 :(得分:2)

inf==inf出于同样的原因,几乎所有浮点数都与自己相等:因为它们相等。它们包含相同的符号,指数和尾数。

你可能在考虑如何NaN != NaN。但这对于一个更重要的不变量来说是一个相对不重要的结果:NaN != x对于任何 x。顾名思义,NaN 根本不是任何数字,因此无法比较等于任何数字,因为所讨论的比较是数字比较(因此为-0 == +0) 。

inf与其他inf进行比较不等于肯定会有一些意义,因为在数学语境中,他们几乎肯定是不平等的。但请记住,浮点平等与绝对数学平等不同; 0.1f * 10.0f != 1.0f1e100f + 1.0f == 1e100f。正如浮点数逐渐下降到非正规数而不会损害尽可能好的平等,所以它们会溢出到无穷大而不会损害尽可能好的平等。

如果您需要inf != inf,则可以模拟它:1e400 == 3e400的计算结果为true,但1e400 - 3e400 == 0的计算结果为false,因为+inf + -inf的结果为{{1} }。 (可以说你可以说它应该评估为NaN,但这对任何人都没有兴趣。)

答案 2 :(得分:1)

<强>背景

在C中,根据IEEE 754二进制浮点标准(因此,如果您使用floatdouble),您将得到一个可以与之完全比较的精确值另一个相同类型的变量。好吧,除非你的计算结果是一个超出可以表示的整数范围的值(即溢出),否则这是真的。

为什么Infinity == Infinity

resAresB IEEE-754标准将无穷大和负无穷大的值分别大于或小于可根据标准(<= INFINITY == 0 11111111111 0000000000000000000000000000000000000000000000000000>= -INFINITY == 1 11111111111 0000000000000000000000000000000000000000000000000000)表示的所有其他值, NaN 除外,它既不小于,等于或大于任何浮点值(甚至本身)。请注意,无穷大和它的负数在其符号,指数和尾数位中都有明确的定义。

因此,resAresB是无穷大的,因为无穷大是明确定义和可重现的,resA==resB。我很确定这是isinf()的实施方式。

为什么NaN!= NaN

但是,没有明确定义NaN。 NaN值的符号位为0,所有1的指数位(就像无穷大而且为负),以及任何非零小数位(Source)。那么,如果他们的分数位是任意的,你怎么能告诉另一个NaN呢?好吧,标准没有假设,当这个结构的两个浮点值相互比较时,只返回false。

更多解释

因为无穷大是明确定义的值(来源,GNU C Manual):

  

无限性通过计算传播

     

2 +∞=∞

     

4÷∞= 0

     

arctan(∞)=π/ 2。

然而,NaN可能会也可能不会通过计算传播。当它发生时,它是一个QNan(Quieting NaN,最重要的分数位集),所有计算都将导致NaN。当它没有时,它是一个SNan(信令NaN,未设置的最重要的分数位),所有计算都将导致错误。

答案 3 :(得分:0)

有许多算术系统。其中一些,包括高中数学中通常涵盖的那些,例如实数,没有无穷大的数字。其他人只有一个无穷大,例如projectively extended real line。其他的,例如正在讨论的IEEE浮点运算,以及extended real line,都有正无穷大。

IEEE754算法在很多方面与实数算术不同,但对于许多目的来说是一个有用的近似。

对NaNs和无穷大的不同处理有逻辑。说正无穷大大于负无穷大和任何有限数是完全合理的。对-1的平方根说任何类似的东西都是不合理的。