浮点数的最大值

时间:2015-08-28 16:31:59

标签: c floating-point

对于以下循环,我希望输出为sum = 20e6,但输出为sum = 1.67772e+07

float sum=0.0f;
for(i=0;i<20e6;i++)
    sum = sum + 1.0f;
printf("sum = %g\n", sum);

问题1:为什么sum浮动无法保存大于1.67772e07的值?

问题2:如果我将循环中的语句更改为sum = sum + 1.001f;,则sum的最终值为2.32229e+07。为什么这个和的值有差异?

问题3:我们是否可以在上面的循环中控制此行为,以便我们可以将float用于大于1.67772e07的值,同时仍然增加1.0f?

1 个答案:

答案 0 :(得分:8)

在某些时候,与x + 1.0f最接近的可表示值是x本身。达到该点后,由于此舍入错误,您的循环不会导致sum进一步增加。

作为一个例子,您可以使用具有固定数量的有效数字的科学记数法来观察此效果。例如,有4位有效数字:

    0 = 0.000e0
    1 = 1.000e0
    2 = 2.000e0
    3 = 3.000e0

...

    9 = 9.000e0
   10 = 1.000e1
   11 = 1.100e1

...

  99 = 9.900e1
 100 = 1.000e2
 101 = 1.010e2

...

  999 = 9.990e2
 1000 = 1.000e3
 1001 = 1.001e3

...

 9999 = 9.999e3
10000 = 1.000e4

如果您再添加一个,则应获得1.0001e4,但由于仅保留了4位有效数字,因此存储的值为1.000e4,例如10000 + 1 = 10000在这个系统中,继续增加只是重复这个计算而不改变结果。

您的代码的工作原理完全相同,只是float使用二进制浮点数,而不是科学数字符号的小数。但是有效二进制数字的数量仍然是有限的,当再添加一个数字并不会改变其中一个有效数字时,sum就会停止增加。

它有点复杂,因为使用二进制,&#34;正确&#34;结果位于两个可表示的数字之间,因此舍入可以向下或向上,在这种情况下,您要求添加1,但实际上得到的结果为2。在任何情况下,一旦可表示值之间的距离变为4,尝试添加一个将无效。