I stumbled upon a problem, where the result of the floating point operation depends on whether I subtract a value now (f
) or later (f2
). Why is that?
int main(int argc, char * argv[])
{
const float fResolution = 0.501f;
const int iDiff = -6; // some values lead to f == f2, like -1, -2, -3, -4 or -5
float f = iDiff * fResolution - 10.0f;
float f2 = iDiff * fResolution;
f2 -= 10.0f;
printf("Difference %f %f %f: %d\n", f, f2, f - f2, iDiff);
return 0;
}
Output: Difference -13.006000 -13.006001 0.000001: -6
I guess, it has something to do with floating point precision, but there are only floats here, so what is the difference between f
and f2
? Or is it maybe a special behavior in Visual Studio 2010?
This is of course a minimal example. In the real world, I extracted the calculation of iDiff * fResolution
into a method, and sometimes subtract -10. The output of my program differed after extracting the method because of the above problem.
Disassembly (Debug Mode):
const float fResolution = 0.501f;
00CC7872 fld dword ptr [__real@3f004189 (0D4AEACh)]
00CC7878 fstp dword ptr [ebp-0F8h]
const int iDiff = -6;
00CC787E mov dword ptr [ebp-104h],0FFFFFFFAh
float f = iDiff * fResolution - 10.0f;
00CC7888 fld dword ptr [ebp-0F8h]
00CC788E fmul qword ptr [__real@c018000000000000 (0D4AED8h)]
00CC7894 fsub qword ptr [__real@4024000000000000 (0D4AE58h)]
00CC789A fstp dword ptr [ebp-110h]
float f2 = iDiff * fResolution;
00CC78A0 fld dword ptr [ebp-0F8h]
00CC78A6 fmul qword ptr [__real@c018000000000000 (0D4AED8h)]
00CC78AC fstp dword ptr [ebp-11Ch]
f2 = f2 - 10.0f;
00CC78B2 fld dword ptr [ebp-11Ch]
00CC78B8 fsub qword ptr [__real@4024000000000000 (0D4AE58h)]
00CC78BE fstp dword ptr [ebp-11Ch]