Lektion
Die Theorie — Gleitkomma282 Wörter
Eine Gleitkommazahl ist eine ganze Zahl, die mit einer Zweierpotenz multipliziert wird: (−1)s × 1.f × 2E−1023. Das Format legt fest, wie viele Bits auf E und wie viele auf f entfallen. Diese einzige Aufteilung bestimmt zugleich, wie weit das Format reicht und wie fein es zwei Zahlen voneinander unterscheiden kann.
Was die einzelnen Symbole bedeuten
s- das Vorzeichenbit, 0 für positiv und 1 für negativ. Es steht für sich allein und wird nicht mit der Zahl verrechnet. Deshalb kennt das Format sowohl eine +0 als auch eine −0.
E- das Exponentenfeld, dem der Wert 1023 hinzuaddiert wird, damit es ohne eigenes Vorzeichen negativ werden kann. Es wählt aus, in welchem Bereich du dich befindest, und dieser Bereich entscheidet darüber, wie weit die Nachbarn voneinander entfernt sind.
f- die Mantisse: 52 Bits, die auf eine führende 1 folgen. Diese 1 wird nie gespeichert, weil eine normalisierte Zahl immer mit einer Eins beginnt. Diese 52 Bits bilden die gesamte Genauigkeit, und der Exponent steuert keine eigene bei.
- Setzt voraus
- Dass die Zahl endlich und normal ist. Unterhalb von 2−1022 fällt die führende 1 weg und das Format läuft weiter, indem es stattdessen Genauigkeit opfert. Die kleinste positive Double-Zahl ist somit 4,94 × 10−324 und besitzt nur noch ein einziges Bit für den Signifikanden.
- Versagt, wenn
- An zwei Stellen, und zwar beide in echtem Code. Der Vergleich zweier berechneter Werte mit
=schlägt fehl, sobald sie über unterschiedliche Wege ermittelt wurden. Verschiedene Wege runden nämlich verschieden. Eine lange Summe hängt zudem von der Reihenfolge ab: Addierst du eine Liste vorwärts und rückwärts, unterscheiden sich die Ergebnisse. Addierst du die kleinsten Terme zuerst, verlierst du am wenigsten.
Aufgabe vollständig gelöst
-
Ein Zahlungssystem speichert Pfundbeträge als binary64. Zeige, dass sowohl £0,10 als auch £0,20 geringfügig zu hoch gespeichert werden und dass ihre Addition nicht £0,30 ergibt. Erkläre zudem, was ein Entwickler von Zahlungssystemen dagegen unternimmt.
-
0,1 im Zweiersystem ist 0,0001 gefolgt von einer 1001, die sich unendlich wiederholt. Ein Zehntel braucht eine Fünf im Nenner, und ein Binärbruch besteht aus nichts als Zweien. Daher bricht die Bruchentwicklung nie ab.
-
53 Binärziffern werden behalten und der Rest wird weggerundet. Hier wird aufgerundet, sodass der gespeicherte Wert um 5,55 × 10⁻¹⁸ über 0,1 liegt. Der Rundungsschritt auf der Seite zeigt diese Richtung als Pfeil an.
-
0,2 besteht aus denselben 53 Ziffern, nur ist der Exponent um eins höher. Sein Fehler ist also genau doppelt so groß: 1,11 × 10⁻¹⁷. Trag 0,2 in das Feld ein und vergleiche die beiden Fehlerkarten.
-
Addiert landen die beiden gespeicherten Werte exakt auf dem Mittelpunkt zwischen den beiden Doubles auf beiden Seiten von 0,3. Bei einem Gleichstand gewinnt der Nachbar, der auf ein gerades Bit endet, und das ist hier der obere.
-
Was also zurückkommt, ist 0,3000000000000000444089209850062616169452667236328125, und jede weitere Berechnung schleppt dies mit sich.
-
Tippe nun 10 und 20 anstelle von 0,1 und 0,2. Beide sind ganze Zahlen deutlich unter 2⁵³, beide werden exakt gespeichert, und 10 + 20 ergibt 30, ohne dass irgendwo etwas verloren geht.
Antwort
Speichere Geld als ganze Zahl der kleinsten Einheit, also in Pence statt in Pfund, und die Arithmetik ist exakt, denn jede Ganzzahl bis 2⁵³ ist exakt. Die einzige verbleibende Rundung ist die, die du selbst schreibst, in dem von dir gewählten Moment, auf die du direkt zeigen kannst. Das Tool zeigt dir beide Hälften in zehn Sekunden: Tippe 0,1 und die Fehlerkarte ist nicht null, tippe 10 und sie ist es.
-