在C中,在使用IEEE-754浮点数的实现中,当我比较两个NaN的浮点数时,它返回0或“false”。 但是为什么两个浮点数都相等呢?
本程序打印“相等:……”(至少在Linux AMD64下使用gcc),在我看来它应该打印“不同:……”。
#include #include 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 * %en",a,c,resA,resB,b,c); } else { printf("different: %e * %e = %e != %e = %e * %en", a, c, resA, resB, b, c); } return EXIT_SUCCESS; }
另一个例子,为什么我认为inf与inf不同,是:自然数和有理数的数量,两者都是无限的但不相同。
那么为什么inf == inf?
无限比例相等,因为这就是标准所说的。 从5.11节比较谓词的细节:
相同符号的无限操作数应相等。
inf==inf
出于同样的原因,几乎所有浮点数都与自己相等:因为它们是相等的。 它们包含相同的符号,指数和尾数。
您可能会想到NaN != NaN
。 但这对于一个更为重要的不变量来说是一个相对不重要的结果:对于任何 x
NaN != x
x
。 顾名思义, NaN
根本不是任何数字 ,因此无法比较任何数字,因为所讨论的比较是数字的(因此为什么-0 == +0
)。
因为在数学语境中,他们几乎肯定是不平等的,因此将inf
与其他inf
进行比较肯定会有一定的意义。 但请记住,浮点平等与绝对数学平等不同; 0.1f * 10.0f != 1.0f
,和1e100f + 1.0f == 1e100f
。 正如浮点数逐渐下降到非正规数而不会损害尽可能好的平等,所以它们会溢出到无穷大而不会损害尽可能好的平等。
如果你想要inf != inf
,你可以模拟它: 1e400 == 3e400
计算结果为true,但是1e400 - 3e400 == 0
计算结果为false,因为+inf + -inf
的结果是NaN
。 (可以说你可以说它应该评估为0
,但这对任何人都没有兴趣。)
背景
在C中,根据IEEE 754二进制浮点标准(因此,如果使用float
或double
float
),您将得到一个精确值,可以与同一类型的另一个变量进行精确比较。 嗯,这是正确的,除非您的计算导致值超出可以表示的整数范围(即溢出)。
为什么Infinity ==无限
resA
和resB
IEEE-754标准将无穷大和负无穷大的值分别大于或小于可根据标准表示的所有其他值( <= INFINITY == 0 11111111111 0000000000000000000000000000000000000000000000000000
和>= -INFINITY == 1 11111111111 0000000000000000000000000000000000000000000000000000
), NaN除外 ,它不小于,等于或大于任何浮点值(甚至自身)。 请注意,无穷大和它的负数在其符号,指数和尾数位中都有明确的定义。
因此, resA
和resB
是无穷大,并且由于无穷大是明确定义和可重现的,因此resA==resB
。 我很确定这是isinf()
的实现方式。
为什么NaN!= NaN
但是,没有明确定义NaN。 NaN值的符号位为0
,所有1
s的指数位(就像无穷大,它是负的),以及任何非零小数位( 源 )。 那么,如果他们的分数位是任意的话,你怎么能告诉另一个NaN呢? 好吧,标准不假设并且当这个结构的两个浮点值相互比较时简单地返回false。
更多解释
因为无穷大是一个明确定义的值(Source, GNU C Manual ):
如你所料,无穷大通过计算传播
2 +∞=∞
4÷∞= 0
arctan(∞)=π/ 2。
但是,NaN可能会也可能不会通过计算传播。 当它发生时,它是一个QNan(Quieting NaN,最重要的分数位集),所有计算都将导致NaN。 当它没有时,它是一个SNan(信令NaN,未设置的最重要的分数位),并且所有计算都将导致错误。
有许多算术系统。 其中一些,包括高中数学通常涵盖的那些,如实数,没有无穷大的数字。 其他人有一个无穷大,例如投射扩展的实线 。 其他的,例如正在讨论的IEEE浮点运算,以及扩展的实线 ,都具有正无穷大和负无穷大。
IEEE754算法在许多方面与实数算术不同,但是对于许多目的而言是有用的近似。
NaNs和无穷大的不同处理有逻辑。 说正无穷大大于负无穷大和任何有限数是完全合理的。 对-1的平方根说任何类似的东西都是不合理的。
以上就是c/c++开发分享C IEEE-Floats inf等于inf相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562458.html