This is one of the surprising aspects of floating-point arithmetic: it actually matters what order you do things like addition in. (Formally, we say that floating-point addition is not commutative.)
It's pretty easy to see why this is the case, with a simpler, slightly artificial example. Let's say you have this addition problem:
1000000. + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
But let's say that you're using a single-precision floating-point format that has only 7 digits of precision. So even though you might think that 1000000.0 + 0.1
would be 1000000.1
, actually it would be rounded off to 1000000.
. So 1000000.0 + 0.1 + 0.1
would also be 1000000.
, and adding in all 10 copies of 0.1
would still result in just 1000000.
, also.
But if instead you tried this:
0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 1000000.
Now, when you add 0.1 + 0.1
, there's no problem with precision, so you get 0.2
. So it you add 0.1
ten times, you get 1.0
. So if you do the whole problem in that order, you'll get 1000001.
.
You can see this yourself. Try this program:
#include <stdio.h>
int main()
{
float f1 = 100000.0, f2 = 0.0;
int i;
for(i = 0; i < 10; i++) {
f1 += 0.1;
f2 += 0.1;
}
f2 += 100000.0;
printf("%.1f %.1f\n", f1, f2);
}
On my computer, this prints 100001.0 100001.0
, as expected. But if I change the two big numbers to 10000000.0
, then it prints 10000000.0 10000001.0
. The two numbers are clearly unequal.