x86和x64上pow的不同结果
我想知道为什么我分别在x86和x64上使用pow
时观察到不同的结果。 在我们的应用程序中,我们控制浮点舍入模式,该模式在Windows和Linux 32位上都能正常工作。
#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;
}
使用Visual Studio 2015进行编译和运行(2012版给出了相同的结果)为我提供了以下输出
86:
Expected 2048.00000000000000000000000, got 2048.00000000000000000000000
Expected 0.12500000000000000000000, got 0.12500000000000000000000
64位:
ERROR: Expected 2048.00000000000000000000000, got 2047.99999999999977262632456
ERROR: Expected 0.12500000000000000000000, got 0.12499999999999998612221
任何人都可以解释不同之处 我知道固有的浮点计算并不精确,但对于这些特定的值,我希望函数能够产生相同的结果,而不管舍入模式如何。
我进一步研究了这一点,发现真正的问题不是如何实现pow
,而是由于Hans Passant提出的x86和x64硬件不同。
有很多不同的pow
可能的实现。 例如, pow(x,y)
是exp(y*ln(x))
。 正如你可以想象的那样, exp(11.0*ln(2.0))
可能会遭受内部舍入误差,即使x
和y
是完全可表示的。
然而,用整数参数调用pow
是相当普遍的,因此一些库为这些情况优化了路径。 例如, pow(x,2*n)
是pow(x,n)
平方, pow(x, 2n+1)
是x*pow(x, 2n)
。
看来你的x86和x64实现在这方面有所不同。 这可能发生。 IEEE只承诺+ - * /和sqrt的精确结果。
链接地址: http://www.djcxy.com/p/66311.html上一篇: Different results for pow on x86 and x64
下一篇: How to build x86 and/or x64 on Windows from command line with CMAKE?