gpt4 book ai didi

c++ - x86 和 x64 上 pow 的不同结果

转载 作者:行者123 更新时间:2023-11-30 05:29:18 26 4
gpt4 key购买 nike

我想知道为什么我在 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 %.23f\n", expected, observed);
}
else {
printf("ERROR: Expected %.23f, got %.23f\n", 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 给出相同的结果)得到以下输出

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

谁能解释一下区别?我知道本质上,浮点计算并不精确,但对于这些特定值,无论舍入模式如何,我都希望函数产生相同的结果。


我对此进行了更多调查,发现真正的问题不是 pow 的实现方式,而是 x86 和 x64 硬件的不同,正如 Hans Passant 所建议的那样。

最佳答案

pow 有许多不同的实现方式。例如,pow(x,y)exp(y*ln(x))。可以想象,即使 xy 可以精确表示,exp(11.0*ln(2.0)) 也会出现内部舍入错误。

但是,使用整数参数调用 pow 是很常见的,因此一些库针对这些情况优化了路径。例如,pow(x,2*n)pow(x,n) 的平方,而 pow(x, 2n+1)x*pow(x, 2n)

看来您的 x86 和 x64 实现在这方面有所不同。那有可能发生。 IEEE 只 promise +-*/和 sqrt 的精确结果。

关于c++ - x86 和 x64 上 pow 的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36477244/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com