Java Runden und genaues Rechnen

Posted: Juli 29th, 2011 | Filed under: Java, Programmieren, Tutorials | Tags: , , , , | No Comments »

Will man in Java ausgerechnete Werte in einer GUI oder auf der Konsole darstellen hat man oft das Problem, dass man sehr lange Nachkommastellen erhält. Addiert man zum Beispiel zehn mal in einer Schleife den Wert 0.1 auf eine Variable die Initial 0 war so erhält man nicht wie erwartet als Ergebnis 1, sondern "0.9999999999999999".

double x = 0; 
for (int i = 0; i < 10; i++) { 
   x = x + 0.1; 

System.out.println(x); 
// Ausgabe: 0.9999999999999999

imageKein Anwender will solche Zahlen auslesen müssen. Leider kommt es beim Rechnen mit Double-Werten immer wieder zu diesem Problem. Dies liegt einfach daran, dass in Java zum Beispiel ein Double-Wert immer nur 64-Bit hat, also es rein logisch gar nicht möglich ist alle Zahlen "abzudecken". Deswegen wird lediglich eine approximative Darstellung einer reellen Zahl durch Double-Werte ermöglicht. Mehr dazu unter http://de.wikipedia.org/wiki/Gleitkommazahl. Der Einsatz von variabel großen Zahlen ist die Lösung für diese Probleme. Java bietet von Haus aus eine solche Klasse an: BigDecimal. Mit ihr ist es möglich mit beliebig großen oder beliebig kleinen Zahlen mit beliebig viel Nachkommastellen zu rechnen. Gerade für das wissenschaftliche Arbeiten zum Beispiel in der Physik wenn es auf Genauigkeit ankommt wäre es natürlich fatal mit Double-Werten zu Rechnen, die bezogen auf die Masse eines Elektrons katastrophale Ungenauigkeiten aufweisen würde.

BigDecimal bietet zusätzlich die Funktion an Zahlen nach mehreren Kriterien zu runden. Dies nutzen wir aus um unseren "vermurksten" Double-Wert zu korrigieren.

import java.math.BigDecimal;
import java.math.RoundingMode;

public class RundenInJava {
  public static void main(String[] args) {
    double x = 0;
    for (int i = 0; i < 10; i++) {
      x = x + 0.1;
    }
    System.out.println(x);
    // Ausgabe: 0.9999999999999999

    BigDecimal xGerundet = new BigDecimal(x);

    // Runden auf 2 Nachkommastellen zur nähsten
    // Nachbarzahl, falls beide Nachbarn gleichweit
    // entfernt sind wird hochgerundet!
    System.out.println((xGerundet.setScale(2, RoundingMode.HALF_UP)).toString());
    // Ausgabe: 1.00
  }
}

BigDecimal bietet natürlich auch alle nötigen Grundrechenarten, anhand von Methoden an, um damit rechnen zu können.



Leave a Reply