Java Runden auf n Kommastellen

Runden auf n Kommastellen

Runden auf Kommastellen geht mit der Funktion Math.round nicht direkt.
Man muss entweder die zu rundende Zahl vorher mit der gewünschten Zehnerpotenz multiplizieren und nach dem Runden wieder dividieren, oder auf die Hilfsklasse NumberFormat der Java Standardbibliothek ausweichen. Wann welche Variante naheliegender ist, schauen wir uns hier an.

Runden auf zwei Nachkommastellen und weiter rechnen

Will man nach dem Runden mit der Zahl weiterrechnen, anstatt sie zum Beispiel einfach nur auszugeben, so empfiehlt sich die Variante mit Math.round und der Multiplikation mit der passenden Zehnerpotenz.
Will man beispielsweise eine Zahl auf zwei Nachkommastellen runden, so könnte das in Java so aussehen:
    double value = 1.23456789;
    value = Math.round(100.0 * value) / 100.0; // Ergebnis: 1.23

Wir sehen: Math.round kann immer nur auf ganze Zahlen runden. Um zwei Nachkommastellen zu erhalten, multiplizieren wir die Zahl vorab mit 100, runden nun auf eine ganze Zahl, und teilen das Zwischenergebnis anschließend wieder durch 100. Dieser kleine Umweg ist mit der Java Standardbibliothek leider notwendig.

Bei drei Nachkommastellen müssten wir dann eben mit 1000 multiplizieren (und anschließend wieder dividieren) usw.
Allgemein gesprochen:
Zum Runden auf n Nachkommastellen multiplizieren wir die Zahl mit 10^n, runden dann, und dividieren das Zwischenergebnis wieder durch 10^n.

Im Programmcode könnte das zum Beispiel so aussehen:

    public double round(final double value, final int frac) {
        return Math.round(Math.pow(10.0, frac) * value) / Math.pow(10.0, frac);
    }

Wer das Laufzeitverhalten optimieren möchte, berechnet die Zehnerpotenz nur einmal, oder legt sich diese Werte (10, 100, 1000, 10000, 100000, ...) direkt beim Programmstart in ein statisches Array.

Runden auf zwei Nachkommastellen zur formatierten Ausgabe

Will man den gerundeten Wert nur ausgeben (zum Beispiel auf dem Bildschirm, oder in eine Text-Datei schreiben), und nicht mit diesem weiterrechnen, so bietet sich die Formatierung als String an. Man wandelt also die Zahl in ein Objekt vom Typ java.lang.String um und führt dabei das Runden auf eine beliebige Anzahl Stellen durch.

Java bietet hierfür die Hilfsklasse java.text.Numberformat an. Damit geht die Formatierung sehr einfach:

    public String roundAndFormat(final double value, final int frac) {
        final java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
        nf.setMaximumFractionDigits(frac);
        return nf.format(new BigDecimal(value));
    }

Dies ist die einfachst mögliche Implementierung. Wer viel rechnet und dabei auf Optimierung angewiesen ist, sollte dann immer die selbe Instanz des NumberFormat-Objekts verwenden, anstatt wie in diesem Beispiel jedes mal ein solches Objekt neu anzulegen.

NumberFormatException und Locale

Wer mit dieser Funktion unachtsam ist, bekommt im weiteren Verlauf schnell eine NumberFormatException, wenn er die erzeugten Strings wieder als Zahl parsen will. Die Ursache ist dann zumeist die vermischte Verwendung von Punkt und Komma als Dezimaltrennzeichen. Wenn dies der Fall ist, muss man mit dem korrekten Locale arbeiten: die Methode getInstance der Klasse NumberFormat kann als Parameter ein Locale entgegennehmen. Locale.US formatiert US-typsich mit dem Punkt als Dezimaltrennzeichen, während Locale.GERMAN ein Komma verwendet.


    public String roundAndFormat(final double value, final int frac, final java.util.Locale locale) {
        final java.text.NumberFormat nf = java.text.NumberFormat.getInstance(locale);
        nf.setMaximumFractionDigits(frac);
        return nf.format(new BigDecimal(value));
    }
    {....}
    roundAndFormat(1.234567, 3, java.util.Locale.US); // ergibt: 1.235 (mit Punkt in der Mitte)
    roundAndFormat(1.234567, 3, java.util.Locale.GERMAN); // ergibt: 1,235 (mit Komma in der Mitte)



Nach oben, Inhaltsverzeichnis, Impressum Admin: Artikel editieren