W środowisku Java 8 zmieniono działanie zaokrąglania liczb dziesiętnych za pomocą metody format klas java.text.NumberFormat i java.text.DecimalFormat, gdy zaokrąglana wartość jest bardzo bliska pozycji zaokrąglania określonej we wzorcu formatowania. Zmiana ta wpływa na liczby o reprezentacji binarnej, która nie jest dokładna.
Na przykład najbliższym przybliżeniem binarnym liczby 0,015, które może uzyskać komputer, jest 0,01499999999999999944488848768742172978818416595458984375. Jeśli liczba ta zostanie zaokrąglona do dwóch cyfr, w języku Java 8 odpowiedzią będzie 0.01, ponieważ 0.004999999... jest mniejsze od 0.005. W poprzednich wersjach języka Java odpowiedzią jest wartość 0,02.
Ta reguła powoduje oznaczenie wywołań metod format klas NumberFormat i DecimalFormat, gdy są one wywoływane z wartością typu podstawowego double lub obiektem java.lang.Double jako pierwszym parametrem.
W poniższym przykładzie przedstawiono sposób użycia metod format.
|
public static void main(String[] args) { java.text.NumberFormat nf = java.text.NumberFormat.getInstance(); nf.setMaximumFractionDigits(3); double aDouble; String myStr; aDouble = 0.8055d; myStr = nf.format(aDouble); System.out.println("format(" + aDouble + ") returns \"" + myStr + "\". Expecting \"0.805\"."); nf.setMaximumFractionDigits(2); aDouble = 0.015d; myStr = nf.format(aDouble); System.out.println("format(" + aDouble + ") returns \"" + myStr + "\". Expecting \"0.01\"."); NumberFormat percent = NumberFormat.getPercentInstance(); percent.setMinimumFractionDigits(1); percent.setMaximumFractionDigits(1); percent.setRoundingMode(RoundingMode.HALF_EVEN); myStr = percent.format(0.5555); System.out.println("format(0.5555) returns \"" + myStr + "\". Expecting \"55.5%\"."); } |
Jeśli ten kod zostanie wywołany w środowisku języka Java 7, zostaną wyświetlone następujące dane wyjściowe:
format(0.8055) zwraca "0.806". Oczekiwano "0.805".W środowisku języka Java 8 wyświetlane są następujące dane wyjściowe:
format(0.8055) zwraca "0.805". Oczekiwano "0.805".Należy pamiętać o tej zmianie działania, ponieważ może mieć wpływ na dane wyjściowe programu. Raport o błędzie JDK-7131459 zawiera więcej informacji i udostępnia kilka powiązanych raportów, w tym raporty o błędach dotyczących środowiska Java 8, w których pojawia się ta regresja.
Więcej informacji na temat klas, których dotyczy ta zmiana, zawierają następujące zasoby: