Thomas Kramer

IT-COW | All posts tagged 'IEEE-754'

IEEE-754 Gleitkommazahlenarithmetik

By Administrator at Juli 13, 2011 17:47
Filed Under: Studium

Eines der ersten Themen im Grundlagen-Fach des Studiums war die IEEE-754 Gleitkommazahlenarithmetik.

 

Nachfolgend will ich eine kurze Zusammenfassung schreiben, aber zunächst einmal möchte ich diesen Link zur Umrechnung von Zahlensystemen vermerken.

 

Allgemein werden Zahlen in der wissenschaftlichen Notation

 

n=f * Basis^e

 

ausgedrückt, wobei f (oder auch m) die Mantisse und e einen positiven oder negativen Exponenten darstellt. Beispiel für das Dezimalsystem:

 

(3,14)10 = (0,314)10 * 10^1 = (3,14)10 * 10^0

 

Das Komma kann verschoben und somit der Exponent entsprechend erhöht oder verringert werden. Das Komma nach rechts zu verschieben bedeutet demnach den Exponenten für jede Stelle um 1 zu verringern – nach links zu verschieben entsprechend zu erhöhen. Diesen Vorgang in eine bestimmte Richtung auszuführen nennt sich Normalisierung.

 

Gemäß Wikipedia muss die Mantisse normalisiert werden um eindeutig bestimmt zu sein, dabei wird zwischen der Wissenschaftlichen Notation mit einer Mantisse zwischen 1 und 9 (bei Dezimalzahlen), der Technischen Notation mit einer Mantisse zwischen 1/f <= m < 1000 (bei Dezimalzahlen) und IEEE-754 (Binärzahlen) mit einer Mantisse zwischen 1 und 2 (1 <= m < 2) unterschieden. Bei dieser Darstellung in Wikipedia wird übrigens noch weiter zwischen normalisierten und normierten Mantissen unterschieden. Bei einer normierten Mantisse ist die Vorkommazahl eine 0 und die erste Nachkommazahl ungleich 0 - bei IEEE-754 benutzt man dagegen normalisierte Mantissen, mit einer Ausnahme für besonders kleine Zahlen.

 

Für das Speichern einer Zahl im IEEE-754-Format muss die Mantisse daher soweit skaliert werden das sie mit 1,x beginnt, weil die Vorkommazahl nicht explizit gespeichert und somit Abweichungen über den Exponenten vorgenommen werden - ich zitiere aus der Wikipedia:

 

Hidden Bit 

Bei der Darstellung normalisierter Mantissen im Binärsystem kann ein Bit eingespart werden. Da die erste Stelle einer normalisierten Zahl immer ungleich 0 ist, ist diese Stelle im Binärsystem immer gleich 1. Eine Ziffer mit dem festen Wert 1 muss nicht mehr explizit gespeichert werden, da sie implizit bekannt ist. Wird diese Möglichkeit genutzt, spricht man von einem hidden bit. Das erwähnte IEEE-Format für Gleitkommazahlen macht von dieser Einsparungsmöglichkeit Gebrauch, nicht jedoch das interne 80-Bit-Format der Intel-CPUs.

Allerdings erzwingt die Verwendung eines Hidden Bit eine gesonderte Darstellung der Null, da jede Mantisse aufgrund des Hidden Bit einen Wert >0 repräsentiert.

 

Zahlen werden wie bekannt im Binärsystem mit der Basis zwei und nicht im Dezimalsystem abgespeichert.

 

Wenn man z. B. die Dezimalzahl 9 speichern möchte rechnet man sie zuerst ins Binärsystem um, das entspricht 1001. Die Darstellung (1001)2 * 2^0 wird dann skaliert auf (1,001)2 * 2^3 - und dies entspricht nun der IEEE-754-Notation. Das Komma wurde nach links verschoben und entsprechend der Exponent für jede Stelle um 1 erhöht. Will man diese Zahl nun über den Taschenrechner ausrechnen muss man sie zuerst wieder ins Dezimalsystem umwandeln - die Darstellung (1,125)10 * 2^3 ist äquivalent zu 9.

 

Ausgehend von dieser IEEE-754-Notation kann man nun die Speicherung vornehmen - aber zunächst weitere Informationen zum Aufbau des IEEE-Standards. IEEE-754 sieht für die Speicherung drei verschiedene Formate vor:

 

  • einfache Genauigkeit mit 32 Bit
  • doppelte Genauigkeit mit 64 Bit
  • erweiterte Genauigkeit mit 80 Bit

 

Grundsätzlich wird eine beliebige Zahl im IEEE-754-System mit einfacher Genauigkeit folgendermaßen gespeichert:

 

0|10000001|11000000000000000000000

 

Die Trennstriche | sind nur als gedankliche Stützhilfe zu verstehen. Die erste Ziffer stellt das Vorzeichen dar, die nachfolgenden acht Zeichen den Exponenten und die 23 Stellen danach die Mantisse. Bei doppelter Genauigkeit wären es dagegen eine Ziffer für das Vorzeichen, 11 für den Exponenten und 52 für die Mantisse.

 

Eine 0 als Vorzeichen bedeutet das es sich um eine positive Zahl handelt, bei 1 ist es dagegen eine negative Zahl. Im Exponenten wird zusätzlich zum eigentlichen Wert noch ein sogenannter Bias oder auch Exzess genannt aufaddiert gespeichert - dieser beträgt bei einfacher Genauigkeit 127 und bei doppelter Genauigkeit 1023. Außerdem beachten muss man wie gesagt das die erste Ziffer der Mantisse nicht explizit mitabgespeichert wird.

 

Angenommen wir haben nun als Zahl

 

1|10000101|10111100000000000000000

 

gespeichert, dann sieht man als erstes dass es sich hierbei um eine negative Zahl handelt. Die 10000101 als Exponenten stellen die Zahl 133 dar, von dieser muss man den Exzess 127 abziehen um den Exponenten 133-127=6 zu erhalten. Berücksichtigt man weitergehend das die erste Ziffer der Mantisse implizit 1 ist und es sich wegen der führenden 1 um eine negative Zahl handelt, ergibt das für die IEEE-754-Notation:

 

(-1,101111)2 * 2^6

 

Wenn man nun also umgekehrt eine Dezimalzahl in IEEE-754 abspeichern will muss man sie zuerst nach binär umwandeln und in die IEEE-754-Notation inklusive Normalisierung bringen. Anschließend muss bei der Umwandlung noch 127 oder 1023 für den Exponenten aufaddiert werden – nicht zu vergessen dass die erste Ziffer der Mantisse gar nicht gespeichert wird und das Vorzeichen ganz an den Anfang der Zahl gebracht wird.

 

Denormalisierte Zahlen im IEEE-754-System

 

Um besonders kleine Zahlen unterhalb der kleinstmöglichen normalisierten Zahl darzustellen gibt es die denormalisierten Zahlen. Bei diesen Zahlen wird der Exponent effektiv auf den Wert 0 gesetzt, es wird kein Exzess mehr aufaddiert. Es wird aber in dieser Konstellation kein Exponent von 0 angenommen, sondern der kleinstmögliche Exponent der normalisierten Zahlen, der -126 bei einfacher Genauigkeit bzw. -1022 bei doppelter Genauigkeit beträgt.

 

Bei einfacher Genauigkeit mit einem Minimum von (0,00000000000000000000001)2 und einem Maximum von (0,11111111111111111111111)2 beträgt die Spanne der (positiven) denormalisierten Zahlen im Dezimalsystem somit

 

(0,00000000000000000000001)2 * 2^-126 = (0,000000119209289)10 * 2^-126 = (1,4012984578504145917853491683059e-45)10


bis

 

(0,11111111111111111111111)2 * 2^-126 = (0,999999880790710)10 * 2^-126 = (1,1754942106924405474329265363998e-38)10

 

Man beachte die Exponenten am Ende der jeweiligen Dezimalzahlen. Effektiv handelt es sich hierbei um Festkommazahlen. Bezüglich denormalisierter Zahlen möchte ich außerdem auf diese ausführliche Darstellung verweisen.

 

Literaturverweise

 

Bei dem mir vorliegenden Abschnitt aus dem Buch Computerarchitektur von Tanenbaum war ich zunächst etwas irritiert, wegen einem bestimmten Beispiel wie eine vorhandene Gleitkommazahl in Binärdarstellung nachträglich normalisiert werden kann. Das Beispiel lautet folgendermaßen

 

Nicht normalisiert:

0|1010100|0000000000011011

Normalisiert:

0|1001001|1101100000000000

 

In der nicht-normalisierten Darstellung dieses Beispiels befindet sich die erste 1 erst an 12. Stelle der Mantisse, daher wurden die verbliebenden 11011 soweit nach links geschoben (bzw. Komma nach rechts) bis sie sich am Anfang befinden und entsprechend wurde für jede Stelle des Verschiebens der Exponent um 1 verringert. Aus dem Exponenten 1010100=84-64=20 wurde somit 1001001=73-64=9.

 

Dieses Beispiel aus dem Buch bezieht sich nicht auf IEEE-754 da nur 7 Stellen für den Exponenten, 11 für die Mantisse und 64 als Wert für den Exzess verwendet werden. Das Beispiel lässt sich aber auch gar nicht auf IEEE-754 anwenden, weil hier eine implizite 0 und keine 1 wie bei IEEE-754 als Vorkommazahl für die Mantisse verwendet wird (und der Exponent ungleich 0 ist).

 

(0,0000000000011011)2 * 2^20 = (0,000411987304687)10 * 2^20 = (432)10

 

ist daher äquivalent zu

 

(0,1101100000000000)2 * 2^9 = (0,84375)10 * 2^9 = (432)10

 

Das war insofern irritierend weil über dem Beispiel IEEE-Standard 754 für Gleitkommazahlenarithmetik als Kopfnote steht und erst darunter Beispiele normalisierter Gleitkommazahlen, es sich also nicht explizit auf IEEE-754 bezieht - der Hinweis das diese Normalisierung dort gar nicht angewandt werden kann fehlt aber gänzlich.

 

Nur wenn man eine 0 als implizite Vorkommazahl annimmt ist diese Normalisierung wie im Buch erwähnt möglich, nicht jedoch mit einer impliziten 1 - aus dieser würde sonst bei der Skalierung 10, 100, 1000 usw. werden und müsste explizit gespeichert werden. Im IEEE-754-Standard gibt es auch die implizite 0 (für denormalisierte Zahlen zwischen den Binärzahlen 0 und 1 und unterhalb der kleinstmöglichen normalisierten Zahl), aber dann muss der Exponent auf 0 gesetzt bleiben - auch damit ist diese Skalierung nicht IEEE-754-konform.

 

Noch ein anderer Verweis auf die Literatur, wobei ich nicht genau weiss ob es sich dabei einfach um einen Fehler handelt. Im Buch Einführung in die Informatik für Naturwissenschaftler und Ingenieure auf Seite 73 steht in einem Beispiel zur Umwandlung einer Dezimalzahl in eine normalisierte Gleitpunktzahl m=(0.11010101)2 für eine normalisierte Mantisse. Das ist aber nicht korrekt, denn laut Wikipedia handelt es sich hierbei um eine normierte und keine normalisierte Mantisse. Das Beispiel bezieht sich aber nicht konkret auf IEEE-754, vermutlich handelt es sich dabei einfach um einen Schreibfehler.

 

Abschließend möchte ich das Java-Applet IEEE-754-Umrechner verlinken.

 

Ergänzung 15.07.2011: Es gibt bereits den Nachfolger IEEE-754r, aber den haben wir im Studium nicht mehr behandelt.

 

Weitere Links


  • Wikipedia zu IEEE-754: Link
  • Papier der FH Flensburg: Link
  • Umwandlung einer Gleitkommazahl in IEEE-754 gemäß Wikipedia: Link
  • Die Mantisse in der Wikipedia: Link
  • Rechner für die Umrechnung von Zahlensystemen: Link
  • IEEE-754-Umrechner: Link
  • Zusammenfassung der Hochschule für Technik und Architektur Bern: Link
  • Mantisse und Exponent: Die mathematische Grundlage für IEEE-754: Link
  • Gleitkommazahlen: Link
  • IEEE-754 in Java: Link

 

Tag-Wolke

Monats-Liste