The short answer; due to round error
(double) 111111111111111.11 != (double) 111111111111111.1
but
(double) 333333333333333.33 == (double) 333333333333333.3
If you want more precision, use setParseBigDecimal and parse will return a BigDecimal.
Why does this happen? This is because you are at the limit of the precision of double. The 17 ones is fine as it can just be represented. The 2's is just double this and as double stores powers of two, every power of two of all 17 ones, so 17 fours and 17 eights is fine.
However, 17 threes takes one more bit than double has to represent the value and this last bit is truncated. Similarly 17 fives, sixes and nines also have rounding errors.
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));
}
prints the following. The double
is rounded slightly before printing and the BigDecimal shows you the exact values the double represents.
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