2015-11-19 7 views
6

次のコードは、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); 
} 

注... 32ビットx86コードが 'GCC -m32' で生成することができ、コルドhttps://stackoverflow.com/users/224132/peter-cordes

参照のことも

is boost::random::uniform_real_distribution supposed to be the same across processors?

---更新@Peterおかげユーザ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... 
+2

あなたは何を得ていますか? – Madivad

+1

"次のコードは、32ビットマシンで変数 'e'と 'f'では異なる結果を出力しますが、64ビットマシンでは同じ結果を出力します。 - マシン/マシンクラスの*特定のペアについてはそれを購入しますが、あなたの主張は原則としてサポートすることはできません。 –

+4

@don:私はあなたのRNG質問の解決を終了しました。これは同じ回答です.x87 FPは80ビットの内部精度を持ち、SSE FPは一時的なものでも64ビットの精度を持っています。私はあなたがこれを最初に尋ねたかったと思う:P私はブーストメルセンヌPRNGの整数部分に32時間対64ビットモードで実行すると違いを探して時間を節約することができた。 –

答えて

10

FLT_EVAL_METHODです。

Cは、FLT_EVAL_METHODに応じてより高い/より広いタイプで中間FP計算を行うことを可能にします。したがって、より広い型が使用され、コードフローが異なる場合、数学的には同じですが、わずかに異なる結果が生じることがあります。 (すべての余分な範囲及び精度を削除)割り当てとキャストを除い


、通常の算術変換を受けるフローティングオペランドと値を持つと浮動小数点定数の演算子によって得られた値は、その形式に評価されます範囲と精度は、型によって要求されるよりも大きくなる可能性があります。評価フォーマットの使用は、FLT_EVAL_METHOD

-1の実装定義の値によって、 と特徴付けられます。不確定;
0.すべての演算と定数を、その型の範囲と精度だけで評価します。
1. double型の範囲と精度に対してfloat型とdouble型の演算と定数を評価し、long double型の範囲と精度に対するlong double演算と定数を評価します。
2.すべての演算と定数をlong double型の の範囲と精度で評価します。
C11dr§5.2.4.2.29

[編集]

@Pascal CuoqFLT_EVAL_METHODの真実性に関する有用なコメントがあります。どのような場合でも、さまざまなコードパスに沿って最適化されたFPコードは、異なる結果を提示することがあります。これは、FLT_EVAL_METHOD != 0またはコンパイラが厳密に準拠していない場合に発生する可能性があります。ポストの詳細について

*、次いで+の2つの動作で行わ操作X*Y + Zは(Y×X)を計算した」fma()と対比することができるが+ zは、1三元操作として丸め:彼らは、値を計算します(現在の丸めモードに従って結果フォーマットに1回丸めます)。 C11§7.12.13.12.結果の違いのもう1つの候補は、 "fma"という行のアプリケーションに起因する可能性があります。e=(c/d)*(b-a)+a;

+0

ありがとうございました。知識を感謝します。 –

関連する問題