为什么浮点运算的结果取决于将一个语句拆分为两个?

时间:2016-07-08 13:54:34

标签: c++ floating-accuracy

我偶然发现了一个问题,其中浮点运算的结果取决于我是否现在减去一个值(f)或更晚(f2)。那是为什么?

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;
}

输出:差异-13.006000 -13.006001 0.000001:-6

我猜,它与浮点精度有关,但这里只有浮点数,那么ff2之间有什么区别?或者它可能是Visual Studio 2010中的特殊行为?

这当然是一个极小的例子。在现实世界中,我将iDiff * fResolution的计算提取到方法中,有时会减去-10。由于上述问题,我的程序输出在提取方法后有所不同。

反汇编(调试模式):

    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] 

0 个答案:

没有答案