繁体   English   中英

1 /(1.0 / 0.0)在C中的值为零

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM