double
ma tylko 15/16 cyfr dokładności, a kiedy dać mu numer nie może reprezentować (który jest przez większość czasu, nawet 0,1 jest niepoprawne) zajmuje najbliższy reprezentowalny numer.
Jeśli chcesz reprezentować dokładnie 9999999999999999
, musisz użyć BigDecimal.
BigDecimal bd = new BigDecimal("9999999999999999");
System.out.println(new DecimalFormat("#.##").format(bd));
drukuje
9999999999999999
Bardzo niewiele rzeczywistych problemów trzeba tę dokładność, ponieważ nie można czegoś zmierzyć to dokładnie tak. tj. do błędu 1 części na kwintillion.
można znaleźć największą reprezentowalna całkowitą z
// search all the powers of 2 until (x + 1) - x != 1
for (long l = 1; l > 0; l <<= 1) {
double d0 = l;
double d1 = l + 1;
if (d1 - d0 != 1) {
System.out.println("Cannot represent " + (l + 1) + " was " + d1);
break;
}
}
wydruków
Cannot represent 9007199254740993 was 9.007199254740992E15
Największy reprezentowalna całkowita jest 9007199254740992 ile potrzebuje jeden mniej trochę (jak sama nawet)
Arytmetyka zmiennoprzecinkowa --- największa tajemnica informatyki od 1985 roku – subsub