【发布时间】:2015-11-19 04:00:57
【问题描述】:
以下代码将在 x86 32 位机器上为变量“e”和“f”输出不同的结果,但在 x86 64 位机器上输出相同的结果。为什么?理论上相同的表达式正在被计算,但从技术上来说它不是。
#include <cstdio>
main()
{
double a,b,c,d,e,f;
a=-8988465674311578540726.0;
b=+8988465674311578540726.0;
c=1925283223.0;
d=4294967296.0;
e=(c/d)*(b-a)+a;
printf("%.80f\n",e);
f=c/d;
f*=(b-a);
f+=a;
printf("%.80f\n",f);
}
注意...可以使用 'gcc -m32' 生成 32 位 x86 代码,感谢@Peter Cordes https://stackoverflow.com/users/224132/peter-cordes
另见
is boost::random::uniform_real_distribution supposed to be the same across processors?
--- 为用户 Madivad 更新
64 bit output
-930037765265417043968.00000...
-930037765265417043968.00000...
32 bit output
-930037765265416519680.00000...
-930037765265417043968.00000...
这个python代码可以给出“数学上正确”的输出
from fractions import Fraction
a=-8988465674311578540726
b=8988465674311578540726
c=1925283223
d=4294967296
print "%.80f" % float(Fraction(c,d)*(b-a)+a)
-930037765265416519680.000...
【问题讨论】:
-
出于好奇,你得到了什么结果?
-
"以下代码将在 32 位机器上为变量 'e' 和 'f' 输出不同的结果,但在 64 位机器上输出相同的结果。" -- 我会为特定对机器/机器类购买它,但作为一般规则,您的断言不能得到支持。
-
@don:我刚刚解决了你的 RNG 问题,答案相同:x87 FP 具有 80 位内部精度,而 SSE FP 具有 64 位精度,即使是临时性的。我希望你先问这个问题:P 我本可以节省一个小时涉足 Boost mersenne PRNG 的整数部分,寻找在 32 位和 64 位模式下运行时的差异。
-
另外,
-m32制作 32 位二进制文件不会“模拟”32 位机器。它确实可以生成可以在 32 位系统上运行的 32 位二进制文件。这就是为什么您需要单独的库包来支持它的原因。现代 64 位 x86 系统安装了两组库,并且可以透明地运行 i386 和 amd64 二进制文件。 (这被称为“多架构”支持,在 Linux 发行版最初移植到 amd64 之后几年才真正稳定下来。但现在只是假设,Windows 也是如此:大多数库的 32 位和 64 位版本。) -
@PeterCordes 完成注释,您应该注意 32 位代码可以使用 x87 指令,但 64 位代码必须使用 SSE。
标签: c++ floating-point precision