Was ist der schnellste Weg, um auf drei Dezimalstellen zu runden?

8

Die SO-Community hatte recht, das Profiling Ihres Codes vor der Frage nach Performance-Fragen scheint mehr Sinn zu ergeben als meine Methode, zufällig zu raten :-) Ich habe meinen Code (sehr intensive Mathematik) profiliert und nicht über 70% meiner Erfahrung gemacht Code ist offensichtlich in einem Teil, den ich nicht für eine Quelle der Verlangsamung, Rundung von Dezimalzahlen hielt.

%Vor%

Mein Problem ist, dass ich Dezimalzahlen bekomme, die normalerweise .01, .02 usw. sind. Aber manchmal bekomme ich etwas wie .070000000001 (Ich interessiere mich wirklich nur für die 0.07, aber Gleitkommapräzision bewirkt, dass meine anderen Formeln fehlschlagen ), Möchte ich einfach die ersten 3 Dezimalstellen, um dieses Problem zu vermeiden.

Gibt es also einen besseren / schnelleren Weg?

    
Error_404 05.04.2012, 03:12
quelle

2 Antworten

15

Der Standardweg zum Runden von (positiven) Zahlen wäre etwa so:

%Vor%

Beispiel 1: floor(1000 * .1234 + 0.5) / 1000 = floor(123.9)/1000 = 0.123
Beispiel 2: floor(1000 * .5678 + 0.5) / 1000 = floor(568.3)/1000 = 0.568

Aber wie @nuakh kommentierte, werden Sie immer von Rundungsfehlern bis zu einem gewissen Grad geplagt sein. Wenn Sie genau 3 Dezimalstellen haben möchten, ist es am besten, in Tausendstel zu konvertieren (also alles mit 1000 zu multiplizieren) und einen ganzzahligen Datentyp zu verwenden ( int , long , usw. .)

In diesem Fall würden Sie die letzte Division um 1000 überspringen und die Integralwerte 123 und 568 für Ihre Berechnungen verwenden. Wenn Sie die Ergebnisse in Form von Prozentsätzen erhalten möchten, teilen Sie diese durch 10:

123 → 12,3%
568 → 56,8%

    
Adam Liss 05.04.2012, 03:17
quelle
3

Die Verwendung eines Gipsverbands ist schneller als die Verwendung von Boden oder Rund. Ich vermute, dass eine Besetzung durch den HotSpot-Compiler stärker optimiert wird.

%Vor%

druckt

%Vor%

Hinweis: ab Java 7 floor (x + 0.5) und round (x) machen Sie nicht das Gleiche wie in diesem Heft. Warum gibt Math.round (0.49999999999999994) 1 zurück

Dies wird korrekt innerhalb des Darstellungsfehlers gerundet. Dies bedeutet, dass, obwohl das Ergebnis nicht genau die Dezimalzahl ist, z. 0.001 wird nicht genau dargestellt, wenn Sie toString () verwenden, wird dies korrigiert. Nur wenn Sie in BigDecimal konvertieren oder eine arithmetische Operation ausführen, wird dieser Darstellungsfehler angezeigt.

    
Peter Lawrey 05.04.2012 06:08
quelle

Tags und Links