以下代码将在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);
}
Run Code Online (Sandbox Code Playgroud)
注意...使用'gcc -m32'可以生成32位x86代码,谢谢@Peter Cordes /sf/users/15689271/
也可以看看
boost :: random :: uniform_real_distribution应该是跨处理器的相同吗?
---为用户Madivad更新
64 bit output
-930037765265417043968.00000...
-930037765265417043968.00000...
32 bit output
-930037765265416519680.00000...
-930037765265417043968.00000...
Run Code Online (Sandbox Code Playgroud)
这个python代码可以给出"数学上正确"的输出
from fractions import Fraction
a=-8988465674311578540726
b=8988465674311578540726
c=1925283223
d=4294967296
print "%.80f" % float(Fraction(c,d)*(b-a)+a)
-930037765265416519680.000...
Run Code Online (Sandbox Code Playgroud) 以下代码在x86 32位与64位处理器上产生不同的输出.
应该这样吗?如果我用std :: uniform_real_distribution替换它并使用-std = c ++ 11编译它会在两个处理器上产生相同的输出.
#include <iostream>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
int main()
{
boost::mt19937 gen;
gen.seed(4294653137UL);
std::cout.precision(1000);
double lo = - std::numeric_limits<double>::max() / 2 ;
double hi = + std::numeric_limits<double>::max() / 2 ;
boost::random::uniform_real_distribution<double> boost_distrib(lo, hi);
std::cout << "lo " << lo << '\n';
std::cout << "hi " << hi << "\n\n";
std::cout << "boost distrib gen " << boost_distrib(gen) << '\n';
}
Run Code Online (Sandbox Code Playgroud)