C - 添加两个单精度浮点正常数,无法得到无穷大的结果

Sha*_*lan 3 c floating-point ieee-754 single-precision

我正在玩浮点运算,我遇到了需要解释的东西.

将舍入模式设置为"朝零"时,又称:

fesetround(FE_TOWARDZERO);
Run Code Online (Sandbox Code Playgroud)

并且添加不同类型的正常正数,我永远无法达到Infinity.

然而,从ieee 745可知,向无穷大的溢出可以通过添加有限数来产生.

例如:

#include <fenv.h>
#include <stdio.h>

float hex2float (int hex_num) {
  return *(float*)&hex_num;
}

void main() {
  int a_int = 0x7f7fffff; // Maximum finite single precision number, about 3.4E38
  int b_int = 0x7f7fffff;
  float a = hex2float(a_int);
  float b = hex2float(b_int);
  float res_add;

  fesetround(FE_TOWARDZERO);  // need to include fenv.h for that
  printf("Calculating... %+e + %+e\n",a,b);
  res_add = a + b;
  printf("Res = %+e\n",res_add);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将舍入模式更改为其他模式,我可能会得到+ INF作为答案.

有人可以解释一下吗?

nju*_*ffa 6

观察到的行为的解释是它由IEEE 754-2008浮点标准强制要求:

7.4溢出

当且仅当目标格式的最大有限数量超出目标格式的最大有限数时,才会发出溢出异常,而圆形浮点结果(见4)的指数范围是无界限的.默认结果应由rounding-direction属性和中间结果的符号确定,如下所示:

[...]

b)roundTowardZero将所有溢出带到格式的最大有限数,并带有中间结果的符号.

因此,对于此处使用的舍入模式(截断或向零舍入),溢出时的结果是最大有限数,而不是无穷大.