2009-07-20 15 views
5

JavaコードをC++に移植しようとしました。私は奇妙な動作を見つけました。私は(たとえコンパイラオプション/ fp:strictがVisual Studio 2008で浮動小数点数の計算が正しいことを意味していても)2倍の加算を得ることはできません。 (:IEEE754によると、厳密な振る舞い/ FP)異なるテストプロジェクトで 特定のVisual Studio 2008プロジェクトでダブルスが正しく追加されないのはなぜですか?

double a = 0.4; 
/* a: 0.40000000000000002, correct */ 

double b = 0.0 + 0.4; 
/* b: 0.40000000596046448, incorrect 
(0 + 0.4 is the same). It's not even close to correct. */ 

double c = 0; 
float f = 0.4f; 
c += f; 
/* c: 0.40000000596046448 too */ 

は、私はそれがうまく動作します設定します。

Visual Studio 2008(標準)を最適化なしで使用し、FP:strictを使用します。

アイデア?それは本当に浮動小数点に切り捨てられますか?このプロジェクトは、JavaとC++の両方で同じ動作が必要です。私はVC++のデバッグウィンドウから読み込んですべての値を得ました。

ソリューション: _fpreset(); // Barry Kellyの考えはそれを解決しました。ライブラリがFP精度を低く設定していました。

+2

コンパイルに使用した正確なコマンドラインとともに小さな完全なテストプログラムを投稿できますか(出力ウィンドウなどを参照)、これは問題を示していますか?私が再現できる唯一の方法は、代わりに0.0f + 0.4fを使うことです。 –

+0

浮動小数点型の不正確さを認識していると思いますか?小数点第7位まで正確であることは、通常、デフォルトの印刷精度が6 @ –

+0

@エヴァンであるため、大丈夫とみなされます。彼の例は、浮動小数点の不正確さによって説明される以上のものです。 – Kevin

答えて

8

私が考えることができるのは、コントロールワードでCPU精度を変更したライブラリまたはDLLとリンクしている可能性があります。

問題のある計算の前にから_fpreset()を呼び出してみましたか?

+0

これらの行に沿ったものでなければなりませんが、計算でも0.0 + 0.4ですか?コンパイル時に評価できないのですか?逆アセンブリをチェックすると、実行時フロートモードに何か関係があるかどうか、またはコンパイル時に何かが間違っているかどうかを確かめることができます。 –

+0

確かにそれは可能かもしれませんが、それが簡単なのであれば、それを再現するのは簡単でしょうか? –

+0

私は気にしません。多分、プロジェクト内の何かが/ fp:stupidまたは同等のものを指定しています。私の個人的なお気に入りは、ソースファイルが改行で終了していないため、プログラムに未定義の動作がありますが、野生のバグの原因となることはあまり期待できません。 –

3

はい、確かに浮動小数点に切り捨てられます。 「不正確」の場合と同じ値の印刷float f = 0.4が表示されます。試してみてください:

double b = 0.0 + (double) 0.4; 

なぜそれが浮動小数点に切り詰められるのですか? 0.0 + 0.4を単精度式として扱うための標準には言い訳がありません。なぜなら、浮動小数点数のリテラルは、別の言い方をするために接尾辞が付いていなければ倍精度であるからです。

何かがあなたの設定に干渉している必要がありますが、私は何が分かりません。

関連する問題