Rundungsfehler und Rechnen mit beliebiger Genauigkeit

Der Rechner rechnet. Plus, minus, mal und vielleicht auch mal geteilt. Die Ergebnisse sind immer richtig. Wirklich? Computer verwenden normalerweise Gleitkommazahlen, bei denen es, trotz ihrer Flexibilität, zu großen Rundungsfehlern kommen kann. Zumindest dann, wenn man viele Berechnungsschritte nacheinander durchführen muss. Kleine Ungenauigkeiten können also zu einem schleichenden Gift für komplexe Berechnungen werden. Ein Ausweg ist das Rechnen mit beliebiger Genauigkeit.

Alice-Wonderland-DrinkMe

„Wenn man viel aus einer Flasche mit der Aufschrift „Gift“ trinkt, wird es einem fast mit Sicherheit nicht bekommen, früher oder später.” – Lewis Carroll

Numerische Ungenauigkeit in der Praxis

OK, her mit dem Windows-Taschenrechner und “Wissenschaftlichen Modus” aktivieren:

√4 – 2 = -8,1648465955514287168521180122928e-39

Eigentlich hätte hier 0 herauskommen müssen, aber Wurzeln sind auch recht problematisch. Nächster Versuch:

10-37 + 1 = 1

Nicht ganz richtig, obwohl das gerundete Ergebnis natürlich schöner aussieht.

Bei der Verwendung von Gleitkommazahlen in Programmiersprachen stößt man auf ähnliche Effekte:

… was dann als Zwischenergebnis 3,0000002 und als Endergebnis 4194304 liefert. Unter Verwendung des Datentyps Double (64-Bit anstatt 32-Bit) sieht es auch nicht besonders vertrauenerweckend aus: Das Zwischenergebnis ist hier 2,9999999999999996 und das Endergebnis diesmal eine sehr große negative Zahl: -2251799813685248. Dies ist kein Fehler in der Gleitkommazahlen-Arithmetik (wie z.B. der FDIV-Bug), sondern das ganz normale Verhalten (wie es im Standard IEEE 754 spezifiziert ist).

Die Fehler sind meistens am Anfang sehr klein, können sich aber im weiteren Rechenweg sehr schnell vergrößern. Einige Beispiele:

  • Das Lösen von Gleichungssystemen ist numerisch sehr instabil. Ein Beispiel, bei dem Hilbert-Matrizen verwendet werden, findet sich auf der Homepage von JLinAlg (mehr zu dieser Open-Source-Bibliothek später).
  • Viele Approximationsalgorithmen, wie man sie z.B. für die Näherung der Kreiszahl π verwendet, konvergieren nicht mehr gegen das korrekte Ergebnis, wenn man sie unter Verwendung von Gleitkommazahlen durchführt. Diese Probleme können oft durch geschickte mathematische Umformung entschärft werden.
  • “Das Versagen von Dhahran”: Am 25.02.1991 traf eine irakische Scud-Rakete eine Kaserne der US-Armee in Dhahran (Saudi Arabien), trotz des vorhandenen Patriot-Raketenabwehrsystems. 28 Soldaten kamen ums Leben, weil eine auf Gleitkommazahlen basierende Berechnung immer ungenauer wurde je länger das zugehörige Radarsystem ununterbrochen in Betrieb war. Nach 100 Stunden konnte das Radarsystem die anfliegende Rakete nicht mehr korrekt erfassen und ignorierte sie als “Messfehler”. Details sind im offiziellen Untersuchungsbericht verfügbar.
Patriot_radar_anmpq53

Radarsystem der Patriot-Rakete

Gleitkommazahlen

Gleitkommazahlen sind darauf ausgelegt numerische Berechnungen, trotz beschränkter Anzahl von Bits, möglichst genau durchzuführen. Im Gegensatz zu einer Festkommazahl, wie z.B. 0,0000042, werden bei Gleitkommazahlen keine Bits an führende oder nachfolgende Nullen verschwendet, sondern so normalisiert wie es auch bei der Exponentialschreibweise üblich ist. So wird z.B. 0,0000042 zu 4,2 · 10-6. Mit Hilfe der Exponentialschreibweise kann man sowohl kleine als auch große Zahlen auf kompakte Art und Weise darstellen. Mit Festkommazahlen benötigt man oft deutlich mehr Platz für die gleiche Information. Zwei Beispiele:

  • Die Planck-Zeit beschreibt das kleinstmögliche Zeitintervall, in dem die Gesetze der Physik, wie wir sie heute kennen, noch gültig sind. Diese physikalische Konstante ist 5,391·10-44 Sekunden. Als Festkommazahl ausgedrückt wäre das: 0,000.000.000.000.000.000.000.000.000.000.000.000.000.000.053.91 Sekunden
  • Die Masse der Erde ist ungefähr 5,974 · 1024 kg. Als Festkommazahl wäre das: 5.974.000.000.000.000.000.000.000 kg

Zusätzlich wird bei Gleitkommazahlen die Darstellung 4,2e-6 für 4,2 · 10-6 verwendet und bei der Gleitkommazahlenarithmetik nach jeder Rechenoperation gerundet und normalisiert (d.h. der Exponent wird neu berechnet). Trotz ihrer großen Flexibilität, sind Gleitkommazahlen oft ungenau, denn viele Zahlen, sogar recht “einfache”, sind nicht mit endlich vielen Ziffern darstellbar. So stellt z.B. die Dezimalzahl 0,0625 (=2-4) auch im Binärsystem kein Problem dar, aber die Dezimalzahl 0,1 hat unendlich viele Nachkommastellen wenn man das Binärsystem verwendet (genau wie bei 1/7 = 0,142857… im Dezimalsystem). Die beste Näherung für 0,1 unter Verwendung von Gleitkommazahlen mit einfacher Genauigkeit ist – zurückgerechnet in eine Dezimalzahl – genau:

0,100000001490116119384765625

Quelle: Wikipedia

Rechnen mit beliebiger Genauigkeit

Wenn es auf zuverlässige Ergebnisse ankommt, sollte besser mit beliebiger Genauigkeit gerechnet werden. Das Open-Source-Projekt JLinAlg bietet (neben anderen Alternativen) verschiedene Datentypen mit beliebiger Genauigkeit an.

jlinalg-logo

Logo von JLinAlg, einer Java-Bibliothek für Lineare Algebra.

Hier nochmal das obige Beispiel unter Verwendung von Bruchzahlen (Rational), wie sie in JLinAlg zur Verfügung stehen:

Als Zwischenergebnis bekommen wir diesmal einfach 3 und in der letzten Zeile erhalten wir die Fehlermeldung, dass versucht wurde durch 0 zu teilen, was auch den Tatsachen entspricht. Ein weiteres Argument für beliebige Genauigkeit ist die leichtere Handhabbarkeit von Ergebnissen. Was ist z.B. 116 / 406? Das Ergebnis sieht folgendermaßen aus:

  • Mit Gleitkommazahlen mit einfacher Genauigkeit (Float): 0.2857143
  • Mit Gleitkommazahlen mit doppelter Genauigkeit (Double): 0.2857142857142857
  • Mit beliebiger Genauigkeit (Rational): 2 / 7

Keines der Ergebnisse ist falsch, aber wirklich genau und handhabbar ist eigentlich nur das letzte. So sieht in diesem Fall die Berechnung mit Hilfe von JLinAlg aus:

Der vollständige Quelltext zu den Beispielen aus diesem Abschnitt findet sich hier.

Fazit

Es ist wichtig, sich der Rundungsprobleme, die bei Gleitkommazahlen auftreten können, bewusst zu sein und diese, falls möglich, zu vermeiden. Es gibt aber auch Fälle, in denen sich der zusätzliche Aufwand für das Rechnen mit beliebiger Genauigkeit lohnt.

Ähnliche Artikel

2 Gedanken zu „Rundungsfehler und Rechnen mit beliebiger Genauigkeit

  1. Benjamin Fröhlich

    Guter Artikel,
    mich hätte aber besonders interessiert, wie man das Rechnen mit beliebiger Genauigkeit erreicht. Vielleicht gibt es hierzu einmal einen Folgeartikel 🙂

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert