[英]1/(1.0/0.0) evaluates to zero in C
在C中评估以下表达式时,输出为零而不是无穷大。 但是按照C运算符优先级规则,输出应为无穷大。
double a=1/(1.0/0.0);
printf("a : %.18le\n", a);
请解释一下gcc编译器如何评估?
C标准没有规定双精度数如何处理NaN和Inf数,但是对于gcc,行为由IEEE 754在严格模式下规定: https : //en.wikipedia.org/wiki/IEEE_754
从那篇文章:
该标准定义了五个异常,每个异常都返回一个默认值,并具有一个相应的状态标志,当异常发生时会引发该状态标志(在某些情况下为下溢除外)。 不需要其他异常处理,但是建议使用其他非默认替代方法(请参见下文)。
五个可能的例外是:
无效运算:数学上未定义,例如负数的平方根。 默认情况下返回qNaN。
除以零:对有限操作数进行的运算会给出确切的无限结果,例如1/0或log(0)。 默认情况下返回±无穷大。
- 溢出:结果太大而无法正确表示(即,其指数范围无限制的指数将大于emax)。 对于四舍五入模式,默认情况下返回±无限。
- 下溢:结果非常小(超出正常范围)并且不精确。 默认情况下返回次正规或零。
- 不精确:精确(即未取整)的结果无法精确表示。 默认情况下,返回正确舍入的结果。
但是,在某些平台上,没有与ieee 754兼容的浮点单元,因此您应该强制执行软件浮点库或就发生的情况查阅平台手册。 例如,arm的fpu具有“ RunFast”模式,这会禁用严格的合规性。
一些进一步的信息: 现实世界中的任何CPU是否不使用IEEE 754?
让我们分解一下表达式:
double a = 1 / (1.0 / 0.0);
首先计算表达式1.0 / 0.0
,结果为+infinity
。
然后对以下表达式求值: 1.0 / +infinity
,结果为0.0
,即您得到的输出。
在评估之前,将int
1
提升为double
。
所有其他答案也适用。
IEEE-754定义的涉及无限的运算基本上遵循非常大的有限数相同的规则。 将1除以n会得到一个随着n变大而接近零的数字,因此四舍五入的限制为零。
除无穷大外,除以无穷大将得出零。 GCC产生正确的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.