For the following loop, I was expecting output to be sum = 20e6
but the output is sum = 1.67772e+07
.
float sum=0.0f;
for(i=0;i<2
At some point, the closest representable value to x + 1.0f
is x
itself. After that point is reached, due to this rounding error your loop won't cause any further increase in sum
.
As an illustration, you can observe this effect using scientific notation with a fixed number of significant figures. For example, with 4 significant figures:
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
and if you add one more, you should get 1.0001e4
, but since only 4 significant digits are preserved, the stored value is 1.000e4
, e.g. 10000 + 1 = 10000 in this system, and continuing to increment just repeats this calculation forever without changing the result.
Your code works exactly the same way, except that float
uses binary floating-point, not decimals as scientific notation does. But the number of significant binary digits is still limited, and when adding one more doesn't change one of those significant digits, sum
ceases to increase.
It's somewhat more complicated, because with binary, the "correct" result is midway between two representable numbers, so rounding could either occur downward or upward, in which case you asked to add 1 but actually get a result 2 higher. In any case, once the distance between representable values becomes 4, trying to add one will have no effect.