Geändertes Verhalten beim Runden in den format-Methoden von NumberFormat und DecimalFormat

Java 8 führt eine Verhaltensänderung beim Rundungsverhalten von Dezimalzahlen mit der Methode format in der java.text.NumberFormat und java.text.DecimalFormat Klassen, wenn der Wert sehr nahe an einer Krawatte liegt und genau an der im Formatierungsmuster angegebenen Rundungsposition sitzt. Die Änderung betrifft Zahlen mit einer binären numerischen Darstellung, die nicht genau ist.

Der genaueste binäre Näherungswert von 0,015, den ein Computer erreichen kann, ist beispielsweise 0,01499999999999999944488848768742172978818416595458984375. Wenn Sie diese Zahl auf zwei Ziffern abrunden, lautet die Antwort in Java 8 .01, weil .004999999 .... ist kleiner als 0,005. In den früheren Versionen von Java ist die Antwort "0,02".

Diese Regel markiert Aufrufe der format-Methoden NumberFormat und DecimalFormat, wenn diese mit einem double-Basiselement oder einem java.lang.DoubleObjekt als erstem Parameter aufgerufen werden. Das folgende Beispiel veranschaulicht die Verwendung der format-Methoden.

< span class="Code"> < span class= "JavaKeyword"> public static void main (< span class="JavaType"> Zeichenfolge [] 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 + ") gibt \" "+ myStr +" \" zurück. Erwartet wird \"0.805\".");

nf.setMaximumFractionDigits(2);
aDouble = 0.015d;
myStr = nf.format(aDouble);
System.out.println("format (" + aDouble + ") gibt \" "+ myStr +" \" zurück. Erwartet wird \"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) gibt \"" + myStr + " \" zurück. Erwartet wird \"55.5% \". ");

}

Wenn Sie diesen Code mit Java 7 aufrufen, wird die folgende Ausgabe angezeigt:

format (0.8055) ergibt "0.806". Erwartet wird "0.805".
format (0.015) gibt "0.02" zurück. Erwartet wird "0.01".
format (0.5555) gibt "55.6%" zurück. Erwartet wird "55.5%".

In Java 8 wird die folgende Ausgabe angezeigt:

format (0.8055) gibt "0.805" zurück. Erwartet wird "0.805".
format (0.015) gibt "0.01" zurück. Erwartet wird "0.01".
format(0.5555) gibt "55.5%" zurück. Erwartet wird "55.5%".

Beachten Sie diese Verhaltensänderung, weil sie sich auf die Ausgabe Ihres Programms auswirken kann. Der Fehlerbericht JDK-7131459 enthält weitere Informationen und verschiedene zugehörige Berichte, einschließlich Fehlerberichten für Java 8, in denen dieses Verhalten als Regression gemeldet werden.

Weitere Informationen zu den betroffenen Klassen finden Sie in den folgenden Quellen: