BigDecimalを使用して、実際の値が何であるかを確認できます。
double a = 0.1;
double c = 0.3;
System.out.println(a + " is actually " + new BigDecimal(a));
System.out.println(c + " is actually " + new BigDecimal(c));
double a3 = a * 3;
System.out.println("0.1 * 3 or " + a3 + " is actually " + new BigDecimal(a3));
double ac = a + c;
System.out.println("0.1 + 0.3 or " + ac + " is actually " + new BigDecimal(ac));
プリント
0.1 is actually 0.1000000000000000055511151231257827021181583404541015625
0.3 is actually 0.299999999999999988897769753748434595763683319091796875
0.1 * 3 or 0.30000000000000004 is actually 0.3000000000000000444089209850062616169452667236328125
0.1 + 0.3 or 0.4 is actually 0.40000000000000002220446049250313080847263336181640625
あなたが見ることができるように、double
は正確に0.1を表現することはできません。 0.1の値を出力すると、表現エラーを隠す小さな丸めが行われます。これは、丸めのない計算を実行し、表現エラーが蓄積されているのを見ることができる場合を除いて、上手く見えます。
0.1 * 3は、目に見える程度の大きさのエラーになります。ただし、0.1 + 0.3は0.4と同じになります(これは、0.1の誤差がわずかに大きすぎ、0.3の誤差がわずかに小さすぎるためです)
http://docs.oracle.com/cd/E19957-01 /806-3568/ncg_goldberg.html – Mysticial