Felder und Variable vom Typ Float (Gleitkomma) werden in den meisten Applikationen für die Speicherung und Verarbeitung von numerischen Daten verwendet, die Nachkommastellen benötigten. Das Format entspricht dem "IEEE 754 double"-Format und belegt 8 Bytes pro Wert. Die Vorteile dieses Variablentyps sind der große Wertebereich (-1.0E307 bis +1.0E307), die ausreichende Genauigkeit (15 Stellen) und die zahlreichen mathematischen Funktionen, die für diesen Typ zur Verfügung stehen. Darüberhinaus ist auch ein binärer Datenaustausch mit anderen Programmen möglich.
Ein Nachteil dieser Gleitkomma-Werte besteht in der binären Kodierung. Während bei ganzzahligen Variablen immer eine exakte Umrechnung von Binär nach Dezimal und umgekehrt möglich ist, gilt dies nicht für Nachkommastellen, die ja einen Bruchteil von 1 darstellen. Beispielsweise ist ein 1/3 nicht mit einer endlichen Zahl dezimaler Nachkommastellen exakt darstellbar (0,3333333….), bei binären Werten ist dies ähnlich. Während es sich bei dezimalen Nachkommastellen um Zehntel, Hunderstel, Tausendstel etc. von 1 handelt, repräsentieren binäre Nachkommastellen die Hälfte, ein Viertel, Achtel, Sechzehntel, Zweiundreißigstel etc. von 1.
Daher lassen sich bestimmte Dezimalwerte nicht als exakte Binärwerte darstellen, die Zahl 17.33 entspricht als Float-Wert eher der Zahl 17,329999999999998. Die Zahl 17.35 liegt dagegen bei 17,350000000000001. Da die Abweichungen zunächst nur an der letzten Stelle auftreten, erscheint der Rundungsfehler vernachlässigbar. Bei einer größeren Anzahl von Rechenschritten kann die Ungenauigkeit jedoch zunehmen, wodurch bei größeren Werten mit vielen Vorkommastellen bereits Abweichungen nach wenigen Stellen hinter dem Komma auftreten können. Viel gefährlicher sind jedoch Funktionen, die die Nachkommastellen einfach abtrennen, wie beispielsweise trn(). trn(17.31 * 100.0) liefert nicht den Wert 1731 sondern 1730 – das Resultat von 17.31 * 100.00 ist 1730,9999999999999, nach Abschneiden der Nachkommastellen verbleibt nur noch 1730. Bei Einsatz der Rundungsfunktion ist das Ergebnis dagegen korrekt: rnd(17.31 * 100.00) liefert 1731.
Als Resümee der Rundungsproblematik sind für den Entwickler zwei Dinge wichtig: Erstens ist der Einsatz der Funktion trn(), ceil(), floor()
und fract()
auf die Fälle zu beschränken, in denen die Auswirkung von Nachkommadifferenzen berücksichtigt werden. Zweitens sollten Zwischenresultate mittels rnd()
auf die erforderlichen Nachkommastellen gerundet werden, um einer schleichende Zunahme von Abweichungen zu begegnen.
Eine Antwort
Es bestätigt sich mal wieder der Spruch aus Studienzeiten:
"Der erfahrene Numeriker mißtraut sogar dem Vorzeichen"