短い答え; ラウンドエラーのため
(double) 111111111111111.11 != (double) 111111111111111.1
しかし
(double) 333333333333333.33 == (double) 333333333333333.3
さらに精度が必要な場合は、setParseBigDecimal を使用すると、parse は BigDecimal を返します。
なぜこれが起こるのですか?これは、double の精度の限界に達しているためです。17個は表現できるので問題ありません。2 はこれの 2 倍であり、double は 2 の累乗を格納するため、17 個すべての 2 の累乗が格納されるため、17 個の 4 と 17 個の 8 は問題ありません。
ただし、17 個の 3 は double が値を表すために必要なビットよりも 1 ビット多く必要であり、この最後のビットは切り捨てられます。同様に、17 個の 5、6、および 9 にも丸め誤差があります。
double[] ds = {
111111111111111.11,
222222222222222.22,
333333333333333.33,
444444444444444.44,
555555555555555.55,
666666666666666.66,
777777777777777.77,
888888888888888.88,
999999999999999.99};
for (double d : ds) {
System.out.println(d + " - " + new BigDecimal(d));
}
以下を出力します。はdouble
印刷前にわずかに丸められ、BigDecimal は double が表す正確な値を示します。
1.1111111111111111E14 - 111111111111111.109375
2.2222222222222222E14 - 222222222222222.21875
3.333333333333333E14 - 333333333333333.3125
4.4444444444444444E14 - 444444444444444.4375
5.5555555555555556E14 - 555555555555555.5625
6.666666666666666E14 - 666666666666666.625
7.777777777777778E14 - 777777777777777.75
8.888888888888889E14 - 888888888888888.875
1.0E15 - 1000000000000000