Numerische Berechnung verwenden praktisch immer gebrochene Zahlen (“Kommazahlen”). Zwei Varianten für die Darstellung von gebrochenen Zahlen durch Bitfolgen:
Festkommazahlen
begrenzte Anzahl Ziffern vor dem Komma,
begrenzte Anzahl Ziffern hinter dem Komma,
Gleitkommazahlen
begrenzte Gesamtanzahl Ziffern,
flexible Position des Kommas (auch weit vor oder hinter der Ziffernfolge).
Festkommazahlen spielen heute nur in Spezialanwendungen eine Rolle, siehe z.B. GNUCash und STM32G4 CORDIC co-processor. Auch werden Festkommazahlen von gängigen Programmiersprachen nur in Ausnahmefällen unterstützt (ein Beispiel ist GNU C). Beschäftigen uns hier deshalb nur mit Gleitkommazahlen genauer.
2.1Darstellung von Gleitkommazahlen¶
Ist die Höchstanzahl der Mantissenziffern (ohne Vorzeichen) festgelegt auf , so gibt es mehrere Paare , die die selbe Zahl darstellen. Beispiel für , :
Man wählt üblicherweise die Darstellung mit der längsten möglichen Mantisse, d.h. die Mantisse hat stets genau Ziffern und die erste Ziffer ist nicht Null. Eine so dargestellte Gleitkommazahl heißt normalisierte Gleitkommazahl. Diese Darstellung ist eindeutig, für Null aber nicht möglich. Wenn nicht anders angegeben, meinen wir mit “Gleitkommazahl” im Folgenden stets eine normalisierte Gleitkommazahl.
Die Ziffernanzahl im Exponent spielt in der numerischen Mathematik nur selten eine Rolle. Die Mantissenlänge ist hingegen ausschlaggebend für die Genauigkeit von Berechnungen. Wenn wir im Folgenden Aussagen der Form “für alle reellen Zahlen gilt...” formulieren, meinen wir damit stets nur solche reellen Zahlen, die betragsmäßig kleiner als die größte darstellbare Gleitkommazahl sind, also keinen Exponentenüberlauf verursachen.
2.2Datenformat für binäre Gleitkommazahlen¶
Für die Umwandlung von Mantisse und Exponent einer binären Gleitkommazahl zu einer Bitfolge spielt heute hauptsächlich der Standard IEEE 754 eine Rolle. Siehe Floating-point arithmetic für Ausnahmen.
Benötigte Bitfolgen für eine normalisierte Gleitkommazahl:
Vorzeichen der Mantisse:
1 Bit,
0 oder 1 für positive bzw. negative Mantisse.
Betrag der Mantisse ohne erste Ziffer:
Bit,
die erste Ziffer ist immer 1, muss also nicht gespeichert werden (“hidden bit”).
transformierter Exponent :
Bit,
,
und markieren spezielle Gleitkommazahlen (siehe unten).
Der Zusammenhang zwischen und entsteht dabei aus der Forderung, dass links und rechts der zweiten Mantissenziffer gleich viele Kommapositionen darstellbar sein sollen:
Der Summand verschiebt das Komma vom Ende der Mantisse zwischen die ersten beiden Ziffern.
Der Summand sorgt für die gleiche Anzahl Kommapositionen links und rechts.
Die durch Vorzeichenbit S, Mantissenbetrag (ohne erste Ziffer) und transformierten Exponent beschriebene Zahl ist also
oder auch
wobei als zu verstehen ist.
Übliche Werte für die Bitanzahl von Mantisse und Exponent bei binären Gleitkommazahlen
| Bezeichnung | Wertebereich von | dezimale Ziffern von | ||
|---|---|---|---|---|
| 16-Bit-Geleitkommazahl | 10 | 5 | ||
| 32-Bit-Geleitkommazahl | 23 | 8 | ||
| 64-Bit-Geleitkommazahl | 52 | 11 |
Spezielle Werte:
markiert die Zahl 0, wenn ; sonst sogenannte denormalisierte Zahlen (behandeln wir hier nicht).
markiert , wenn ; sonst “NaN”, also ungültige Zahl.
Ungültige Zahlen entstehen z.B. als Ergebnis der Division 0/0. Unendliche Werte entstehen zum z.B. bei 1/0 (dann ) oder -1/0 (dann ). Die Zahl 0 hat dabei ebenfalls ein Vorzeichen. Betragskleine negative Zahlen werden auf -0 gerundet, positive auf +0. Somit kann 1/0 auch ergeben, wenn die 0 durch Runden einer negativen Zahl entstanden ist.
2.3Runden¶
Das übliche Rundungsverfahren für Gleitkommazahlen entspricht nicht exakt dem mathematischen Runden.
Beim mathematischen Runden wird in der zweiten Regel immer die größere der beiden möglichen Zahlen gewählt. Dies führt jedoch zur statistischen Drift.
Beispiel: Rechnen mit 2 Kommastellen. Mittelwert der 10 Werte 0.105, 0.115, 0.125, 0.135, 0.145, 0.155, 0.165, 0.175, 0.185, 0.195 ist 0.15 bzw. 0.16 je nach verwendeter Rundungsregel (IDVID 230).
Die Schranke für den relativen Rundungsfehler heißt Maschinenepsilon. Aus der Dreiecksungleichung folgen
und
(IDVID 260). Diese Ungleichungen spielen eine wichtige Rolle bei der Fehleranalyse von Algorithmen. Insbesondere existiert zu jedem reellen ein mit
2.4Grundoperationen¶
Einige grundlegende Operationen, die nach IEEE 754 mit korrektem Runden implementiert sein müssen (meist direkt in der Hardware):
Addition, Subtraktion,
Multiplikation, Division,
Quadratwurzel,
Umwandlung in Ganzzahl,
Umwandlung zwischen den verschiedenen Bitanzahlen.
Praktisch alle Prozessoren bieten viele weitere Operationen an. Siehe z.B. Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture (ab Abschnitt 8.3.7). Mathematische Bibliotheken liegen üblicherweise in an die verschiedenen Prozessoren angepassten Versionen vor, sodass möglichst viele Operationen direkt auf der Hardware ausgeführt werden können.
Als Maß für die Rechengeschwindigkeit eines Prozessors werden gern FLOPS (floating-point operations per second, auch: flop/s) angegeben. Eine “floating-point operation” ist dabei meist als kombinierte Addition und Multiplikation zu verstehen. Es gibt jedoch keine allgemein anerkannte feste Definition dieser Einheit! Die Umrechnungen von FLOPS in Prozessortakte ist prozessorabhängig; siehe Floating point operations per second für die Umrechnungsfaktoren bei üblichen Prozessoren. Die Prozessortaktanzahlen für verschiedene Operationen findet man zum Beispiel in 4. Instruction tables: Lists of instruction latencies, throughputs and micro-operation breakdowns for Intel, AMD, and VIA CPUs (Spalte “Latency”, z.B. Seite 369 für Intel-Ice-Lake-Prozessoren).
2.5Hinweise für die Praxis¶
Der IEEE-754-Standard überlässt einige Details der konkreten Implementierung, sodass Programmcode sich auf unterschiedlichen Prozessorarchitekturen und bezüglich unterschiedlicher Compiler und Bibliotheken eventuell unterschiedlich verhält, siehe z.B. Floating-Point Determinism.
Auch setzen die meisten Compiler Codeoptimierung ein, wobei zu Gunsten von Geschwindigkeit auf Genauigkeit verzichtet wird. Die Optimierung lässt sich über zahlreiche Optionen steuern/abschalten. Für GNU C siehe Options That Control Optimization, für Microsoft C++ siehe /fp (Specify floating-point behavior).
Nicht nur mit Blick auf Abweichungen zwischen erwarteter und tatsächlich erzielter Genauigkeit sind diese Aspekte interessant, sondern auch mit Blick auf Reproducible Builds.
Für weitere “Randthemen” und Probleme bei der Verwendung von Gleitkommazahlen siehe auch Random ASCII – tech blog of Bruce Dawson (Category Archives: Floating Point).

“10 minutes ago we were down to only 2 0s!” “How many do we have now?” “I ... don’t know!!” Quelle: Randall Munroe, xkcd.com/3009