gpt4 book ai didi

c++ - 双数组求和结果在WIN32和WIN64上与C++不一致

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:41 24 4
gpt4 key购买 nike

我现在正在开发一个程序,要求在 WIN32 和 WIN64 上结果一致。我发现的一个困难是,在这些平台上对 double 组值求和可能会导致结果不一致。以我的代码片段为例:

            double sum=0;
std::vector<double>::iterator itW = weighting.begin();
for(std::vector<double>::iterator it = x_array.begin(); it<x_array.end(); it++,itW++)
sum += (*it)*(*it)*(*itW);

在上面的代码片段中,计算了加权平方值数组求和。 x_array 值如下所示:

    [size]  982 long
[capacity] 982 long
[0] 202.00000000000000 double
[1] 202.00000000000000 double
[2] 202.00000000000000 double
[3] 202.00000000000000 double
[4] 201.00000000000000 double
[5] 201.00000000000000 double
[6] 201.00000000000000 double
[7] 201.00000000000000 double

weighting 数组看起来像:

    [size]  982 long
[capacity] 982 long
[0] 3.8144169965399290e-015 double
[1] 1.0367629020002889e-014 double
[2] 2.8179334245287864e-014 double
[3] 7.6591752750373270e-014 double
[4] 2.0526158725409399e-013 double
[5] 5.5790334162148110e-013 double
[6] 1.5163876629635047e-012 double
[7] 4.1215590100336753e-012 double

我仔细检查了一下,在两个平台上 x_arrayweighing 都有相同的值。但是,总和不同,在 WIN32 上总和为 575994.17931926867,而在 WIN64 上总和为 575994.17931926856。任何想法为什么结果不一致?

编辑: (1) 我是用Visual Studio 2010编译的。 (2)/fp precise 和 strict 同时使用,但不改变结果。

最佳答案

我注意到在 64 位编译中,MSVC 编译器更喜欢使用 SSE 指令,大概是为了通过 SIMD 提高速度。在 32 位编译中,它使用较旧的集成 x87 FPU 指令。

x87 浮点单元使用扩展精度 80 位浮点寄存器。根据您的编译器优化设置,编译器会将中间累加结果(您的变量和)存储在 80 位精度的寄存器中。使用了这个额外的 16 位精度,因为将两个 double 相乘会在截断前得到一个 128 位精度的数。

SSE 寄存器是 64 位 IEEE double 浮点寄存器。因此,您在第 16 位十进制数字中损失了一点累积精度 - 这大约是您期望 FP 截断错误出现在任何具有 double 的正数乘积的简单总和中的位置。

有关详细信息,请参阅 "What Every Computer Scientist Should Know About Floating-Point Arithmetic" Goldberg 1991 ACM.

关于c++ - 双数组求和结果在WIN32和WIN64上与C++不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28233006/

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