dポイントプレゼントキャンペーン実施中!

Java初心者です。
よろしくお願いいたします。

double型の変数に数値を代入して、足し算をするプログラムを組んだとして、

例えば、
10.5 と 1.5 を 代入すると、答えは 12.0 になりました。
問題ないです。

しかし、
数値をいろいろ変更してみると、おかしな答えになるケースがある事を発見しました。

例えば、
4.1 と 3.8 を代入すると、 7.8999999999999995 となったり、

1.8 と 2.1 を代入すると、 3.9000000000000004 となったりするのです。

なぜそうなるのか、よくわかりません。
わかり易い解説をして頂けると嬉しく思います。
よろしくお願いいたします。

A 回答 (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);
    • good
    • 0

double 型は IEEE754の倍精度浮動小数点 という形式で


数値を保持します。この形式は、10進で書いたリテラルの実数値を
誤差なく保持できない場合が多々あるのでこうなります。


http://ja.wikipedia.org/wiki/IEEE_754

これは Java というよりプログラミングの基本ですが、
不思議なことに、ちゃんと勉強している人がなぜか非常に少ないんですよね。

頑張ってください。
    • good
    • 0

浮動小数点だから。



Excelでの例だけど、浮動小数点の誤差について解説されています。
http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.s …
    • good
    • 0

「浮動小数点」を調べてみてください。

    • good
    • 0

double型の値が内部的にどのように表現されているかを調べてみてはどうでしょうか.

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!