- ベストアンサー
double型の足し算でおかしな答えになる事例
- double型の足し算において、一部の数値でおかしな答えになるケースがあることがわかりました。
- 例えば、4.1と3.8を足し算すると7.899999999999995となる場合や、1.8と2.1を足し算すると3.9000000000004となる場合があります。
- このような問題が起きるのは、double型が2進数で数値を表現するために正確に表現しきれないことが原因です。小数部分のみで表される値は、有限桁の2進数では正確に表現できないので、微小な誤差が発生することがあります。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
次のJavaプログラムを実行してみてください。 class Q7461149 { public static void main(String[] args) { double d1 = 10.5; double d2 = 1.5; System.out.println(d1); System.out.println(d2); System.out.println(d1 + d2); System.out.println(Double.toHexString(d1)); System.out.println(Double.toHexString(d2)); System.out.println(Double.toHexString(d1 + d2)); } } ---------------------------------------- 10進数の 10.5 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.5p3, これは2進表記で (1.0101)2 × 2の3乗を表しています。 (1+ 1/4 + 1/16)×8 = 10.5ということです。 10進数の 1.5 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.8p0, これは2進表記で (1.1000)2 × 2の0乗を表しています。 (1+ 1/2)×1 = 1.5ということです。 両者の和は,指数を2の3乗に統一することで計算でき, {(1.0101)2 + (0.0011000)2}×2の3乗 = (1.1)2 × 2の3乗です。 10進数の10.5 と 10進数の1.5,どちらも, 1,1/2,1/4,1/8,1/16 といった有限長の2進数の組合せで びったり正確に表現できる数だったということです。 ---------------------------------------- 次に d1,d2 の値を次のように変更してみます。 double d1 = 4.1; double d2 = 3.8; 10進数の 4.1 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.0666666666666p2 となります。これは2進表記で (1.0000 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110)2 × 2の2乗 となる「循環無限小数」であり,同パターンの繰り返しがどこまでも続きます。 つまり10進数の 4.1 は,1,1/2,1/4,1/8,1/16 …といった 有限長の2進数の組合せでは,ぴったり正確に表現できないのです。 10進数の 3.8 も同様であり,d1+d2 に誤差が生じる理由はこれです。 ---------------------------------------- このような例を「おかしな答え」だとお感じになるのなら, double型の変数の中身全体をそのまま出力するのではなく, 小数点以下の桁数を若干短くして出力してみてください。 例えば次のように書くと, 小数点以下の表示を15けたまでに限定できます。 System.out.printf("%.15f", d1 + d2);
その他の回答 (4)
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
double 型は IEEE754の倍精度浮動小数点 という形式で 数値を保持します。この形式は、10進で書いたリテラルの実数値を 誤差なく保持できない場合が多々あるのでこうなります。 http://ja.wikipedia.org/wiki/IEEE_754 これは Java というよりプログラミングの基本ですが、 不思議なことに、ちゃんと勉強している人がなぜか非常に少ないんですよね。 頑張ってください。
- bajutsu
- ベストアンサー率20% (139/693)
浮動小数点だから。 Excelでの例だけど、浮動小数点の誤差について解説されています。 http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.shtml
- wormhole
- ベストアンサー率28% (1626/5665)
「浮動小数点」を調べてみてください。
- Tacosan
- ベストアンサー率23% (3656/15482)
double型の値が内部的にどのように表現されているかを調べてみてはどうでしょうか.