Ich benutze jdk 1.8.0_45 und unsere Tests haben einen Fehler im Rouding entdeckt. RoundingMode.HALF_DOWN funktioniert genauso wie RoundingMode.HALF_UP, wenn die letzte Dezimalzahl, die die Rundung entscheidet, 5 ist.
Ich habe verwandte Probleme mit RoundingMode.HALF_UP gefunden, aber sie sind in Update 40 behoben. Ich habe dem Orakel auch einen Fehler hinzugefügt, aber meiner Erfahrung nach reagieren sie wirklich nicht.
%Vor%Tatsächliches Ergebnis: Abrunden 10.5556 Zusammenfassen 10.5556
Erwartetes Ergebnis (mit jdk 1.7 erhalten): Abrunden 10.5555 Zusammenfassen 10.5556
Scheint, dass es geändert werden soll. Das JDK 1.7-Verhalten war falsch.
Das Problem ist, dass Sie einfach nicht die Zahl 10.55555
mit dem double
-Typ darstellen können. Es speichert die Daten im IEEE-Binärformat. Wenn Sie also der 10.55555
-Variable die dezimal double
-Nummer zuweisen, erhalten Sie tatsächlich den nächsten Wert, der im IEEE-Format dargestellt werden kann: 10.555550000000000210320649784989655017852783203125
. Diese Zahl ist größer als 10.55555
, daher ist sie richtig auf 10.5556
in HALF_DOWN
mode gerundet.
Sie können einige Zahlen überprüfen, die im Binärformat genau dargestellt werden können. Zum Beispiel 10.15625
(das ist 10 + 5/32
, also 1010.00101
in binär). Diese Zahl wird auf 10.1562
in HALF_DOWN
mode und 10.1563
in HALF_UP
mode aufgerundet.
Wenn Sie das alte Verhalten wiederherstellen möchten, können Sie Ihre Nummer zuerst in BigDecimal
konvertieren, indem Sie BigDecimal.valueOf
Konstruktor, der ein double
in ein BigDecimal
übersetzt, indem er die kanonische Zeichenkette" double
"verwendet:
Die Änderung des Verhaltens ist in den Versionshinweisen von Java 8
Bei Verwendung der Klassen
NumberFormat
undDecimalFormat
war das Rundungsverhalten früherer JDK-Versionen in einigen Fällen falsch. [...]Wenn Sie beispielsweise das standardmäßig empfohlene
NumberFormatFormat
API-Formular verwenden:NumberFormat nf = java.text.NumberFormat.getInstance()
gefolgt vonnf.format(0.8055d)
, wird der Wert 0.8055d im Computer als 0.80549999999999999378275106209912337362766265869140625 aufgezeichnet, da dieser Wert nicht genau im Binärformat dargestellt werden kann. Hier ist die Standard-Rundungsregel "halb-gerade", und das Ergebnis des Aufrufs von format () in JDK 7 ist eine falsche Ausgabe von "0.806", während das korrekte Ergebnis "0.805" ist, da der Wert von Computer ist "unter" der Krawatte.Dieses neue Verhalten wird auch für alle Rundungspositionen implementiert, die durch ein vom Programmierer gewähltes Muster definiert werden können (keine Standardmuster).
Tags und Links java java-8 migration rounding number-rounding