Zauważ, że miałbyś ten sam problem, gdybyś użył arytmetyki dziesiętnej o ograniczonej precyzji i chciałbyś sobie poradzić z 1/3: 0,333333333 * 3 to 0,999999999, a nie 1,00000000.
Niestety, 5,6, 5,8 i 11,4 po prostu nie są liczbami okrągłymi w systemie binarnym, ponieważ obejmują one piąte. Więc ich reprezentacja zmiennoprzecinkowa nie jest dokładna, tak jak 0,3333 nie jest dokładnie 1/3.
Jeśli wszystkie używane liczby nie są liczbami dziesiętnymi, a chcesz uzyskać dokładne wyniki, użyj funkcji BigDecimal. Lub, jak powiedzieli inni, jeśli twoje wartości są jak pieniądze w tym sensie, że wszystkie są wielokrotnością 0,01 lub 0,001, lub coś podobnego, pomnóż wszystko przez stałą potęgę 10 i użyj int lub long (dodawanie i odejmowanie to trywialne: uważaj na mnożenie).
Jeśli jednak jesteś zadowolony z binarnego do obliczeń, ale chcesz po prostu wydrukować rzeczy w nieco bardziej przyjaznym formacie, wypróbuj java.util.Formatter
lub String.format
. W ciągu formatu określ precyzję mniejszą niż pełna precyzja double. Do 10 cyfr znaczących, powiedzmy, 11,399999999999 to 11,4, więc wynik będzie prawie tak samo dokładny i bardziej czytelny dla człowieka w przypadkach, gdy wynik binarny jest bardzo zbliżony do wartości wymagającej tylko kilku miejsc po przecinku.
Precyzja do określenia zależy trochę od tego, ile matematyki wykonałeś na swoich liczbach - ogólnie im więcej zrobisz, tym więcej błędów będzie się kumulować, ale niektóre algorytmy kumulują go znacznie szybciej niż inne (nazywane są „niestabilnymi”, w przeciwieństwie do „stabilnego” w odniesieniu do błędów zaokrąglania). Jeśli wszystko, co robisz, to dodawanie kilku wartości, to domyślam się, że upuszczenie tylko jednego miejsca po przecinku precyzji rozwiąże problem. Eksperyment.