Different results for pow on x86 and x64

I am wondering why I am observering different results when using pow on x86 and x64 respectively. In our application we control the floating point rounding mode, which has worked fine on both Windows and Linux 32 bit.

#include <cmath>
#include <cstdio>
#include <cfloat>

void checkEqual(double expected, double observed) {   
    if (expected == observed) {
        printf("Expected %.23f, got %.23fn", expected, observed);
    }
    else {
        printf("ERROR: Expected %.23f, got %.23fn", expected, observed);
    }
}

int main(int argc, char **argv) {   
    unsigned ret, tmp;
    _controlfp_s(&ret, 0, 0);
    _controlfp_s(&tmp, RC_DOWN, MCW_RC);

    checkEqual(2048.0, pow(2.0, 11.0));
    checkEqual(0.125, pow(2.0, -3.0));

    return 0;   
}

Compiling and running with Visual Studio 2015 (2012 gives the same result) gives me the following output

x86:

Expected 2048.00000000000000000000000, got 2048.00000000000000000000000
Expected 0.12500000000000000000000, got 0.12500000000000000000000

x64:

ERROR: Expected 2048.00000000000000000000000, got  2047.99999999999977262632456
ERROR: Expected 0.12500000000000000000000, got 0.12499999999999998612221

Can anyone explain the differences? I know that inherently, floating point calculations are not exact, but for these specific values, I would expect the function to produce the same result regardless of rounding mode.


I investigated this some more and found that the real issue is not how pow is implemented but rather that x86 and x64 hardware are different as Hans Passant suggested.


There are many different implementations of pow possible. For instance, pow(x,y) is exp(y*ln(x)) . As you can imagine, exp(11.0*ln(2.0)) can suffer from internal rounding errors even though x and y are exactly representable.

However, it's quite common to call pow with integer arguments, and therefore some libraries have optimized paths for those cases. Eg, pow(x,2*n) is pow(x,n) squared, and pow(x, 2n+1) is x*pow(x, 2n) .

It seems your x86 and x64 implementations differ in this respect. That can happen. IEEE only promises precise results for +-*/ and sqrt.

链接地址: http://www.djcxy.com/p/66312.html

上一篇: 为什么多维数组的枚举值不等于自身?

下一篇: x86和x64上pow的不同结果