浮点数的最大值

对于以下循环,我期望输出为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; 那么总和的最终值是2.32229e+07 。 为什么这个总和的价值不同?

问题3:我们可以在上面的循环中控制这种行为,这样我们可以使用float大于1.67772e07值,同时仍然增加1.0f吗?

在某些时候, 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不再增加。

它有点复杂,因为对于二进制,“正确”结果位于两个可表示数字之间,因此四舍五入可能向下或向上发生,在这种情况下,您要求添加1但实际上得到的结果更高2。 在任何情况下,一旦可表示值之间的距离变为4,尝试添加一个将不起作用。