2

我想这是一个相当基本的问题,但我不知道为什么这两段代码会给出不同的结果。Pentium 处理变量 Divider 的方式是否不同于中间值( 256.0 / (double)k )?

int j=64, k=20;  
double x, y, Divider;

Divider = 256.0 / (double)k;
x = (double)j / Divider - 5.0;
y = (double)j / ( 256.0 / (double)k ) - 5.0;

结果:x = -2.77555756156289E-16 y = 0.0

作为参考,我使用的是 Embarcadero 的 XE3 C++ Builder,它提供了与 Builder 6 相同的结果。我在两者上都使用了默认编译器设置。

4

2 回答 2

2

问题是,当您不使用 SSE 指令时,编译器可能会选择使用本机387浮点单元进行中间计算,该单元使用 80 位值进行所有计算。

在 的计算中x,您通过将中间值存储在 中来强制将其截断为 64 位Divisor。然后下一个除法使用一个已经四舍五入的除数;由于除法的精度足够高,因此结果与 5.0 略有不同。

在 的计算中y,除法以 80 位精度完成,因此结果更接近 5.0(足够接近,截断到 64 位使其为 0)。

如果您使用 SSE(只有 64 位寄存器),您也会得到两个0值,或者强制编译器以 64 位精度进行所有计算。

于 2013-09-05T15:27:08.083 回答
0

也许它是优化器。在第二个

y = (double)j / ( 256.0 / (double)k )

在数学上与

y = (double)j * (double)k / 256.0

这只进行一次除法(巧合地干净地除法)并且舍入误差较小。

因为x它被迫做两个部门。

于 2013-09-05T14:50:54.043 回答