Erklärungen zur Gleitkommadarstellung Auszüge aus “Rechnerentwurf” von R.Hoffmann zum Thema Gleitkommadarstellung mit ergänzenden Kommentaren und Beispielen von Patrik Schmittat 23. Juni 2008, Darmstadt Inhaltsverzeichnis 0.1 0.2 Einführung in dieses Dokument . . . . . . . . . . . . . . . . . Gleitkommazahlen und das IEEE754 Gleitkommaformat . . . 0.2.1 Einleitende Worte . . . . . . . . . . . . . . . . . . . . 0.2.2 IEEE754-32-Bit-Gleitkommmaformat . . . . . . . . . Zahlenbeispiele . . . . . . . . . . . . . . . . . . . . . . Weitere Interpretationen der Darstellung . . . . . . . Änderung des Standards IEEE754 . . . . . . . . . . . 0.2.3 IEEE754-64-Bit-Gleitkommmaformat . . . . . . . . . 0.2.4 Umrechenmethoden . . . . . . . . . . . . . . . . . . . Dezimal → Gleitkomma (an dem Beispiel von 42.375) Methode 1: . . . . . . . . . . . . . . . . . . . . Methode 2: . . . . . . . . . . . . . . . . . . . . Gleitkomma → Dezimal (an dem Beispiel von 42.375) Methode 1: . . . . . . . . . . . . . . . . . . . . Methode 2: . . . . . . . . . . . . . . . . . . . . Applets zur Konvertierung . . . . . . . . . . . . . . . 0.2.5 Operationen mit Gleitkommazahlen . . . . . . . . . . Addition/Subtraktion von Gleitkommazahlen . . . . . Beispiele . . . . . . . . . . . . . . . . . . . . . . Beispiel 1 . . . . . . . . . . . . . . . . . . . Beispiel 2 . . . . . . . . . . . . . . . . . . . Multiplikation von Gleitkommazahlen . . . . . . . . . Beispiele . . . . . . . . . . . . . . . . . . . . . . Beispiel 1 . . . . . . . . . . . . . . . . . . . Beispiel 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3 3 5 7 7 8 8 9 9 9 10 10 11 11 11 11 12 13 13 13 14 15 15 16 0.1 Einführung in dieses Dokument Dieses kleine Handout soll eine weitere Erklärung zu dem Thema “Gleitkommadarstellung” sein. Es stellt den Inhalt nochmal in einem anderen Licht dar, als in der Vorlesung1 erstmals diskutiert. Die folgenden Kapitel sind Auszüge aus dem Buch “Rechnerentwurf” von R. Hoffmann [Hof93] und wurden von Patrik Schmittat mit Beispielen versehen. Für weitere Referenzen kann man folgende Quellen in betracht ziehen: • die Homepage des IEEE Standards [IEE08b] 1 Technische Grundlagen der Informatik 2 - TGdI 2, SS08 2 • das Standardwerk von Patterson und Hennessy [PH98, s. S. 277 - 288] Dies sind jedoch weiterführende Quellen und sollen als Horizonterweiterung dienen, können somit auch über den, in der Vorlesung behandelten, Stoff hinaus gehen. 0.2 Gleitkommazahlen und das IEEE754 Gleitkommaformat 0.2.1 Einleitende Worte Durch ein Codewort mit n Bits lassen sich 2n verschiedene Zahlen repräsentieren. Wenn wir das Codewort z.B. als Vorzeichenzahl interpretieren, dann lassen sich die Werte von −(2n−1 − 1) bis +(2n−1 − 1) in Abständen von 1 darstellen. Dabei haben wir uns ganze Zahlen vorgestellt, mit einem fiktiven Komma, das ganz rechts steht. Wenn wir das Komma um m Stellen nach links verschieben, dann bedeutet dies eine Division durch 2m . Die Abstände zwischen den Zahlen betragen jetzt 2−m , wodurch sich näherungsweise rationale Zahlen darstellen lassen. Wird das Komma um m Stellen nach rechts verschoben, dann lassen sich noch sehr große Zahlen darstellen, allerdings nur mit dem Abstand 2m . Wir sprechen von einer Festkommazahl, wenn wir uns das Komma an einer festen Stelle vorstellen. Verwenden wir zusätzliche Bits, die die Stellung des Kommas angeben, dann sprechen wir von einer Gleitkommazahl (floating point number) oder einer halblogarithmischen Darstellung. Der Vorteil der Gleitkommazahl gegenüber der Festkommazahl besteht nun darin, daß ein wesentlich größerer Wertebereich mit der gleichen Anzahl von Bits dargestellt werden kann, so dass bei arithmetischen Operationen nur selten die Bereichsgrenzen (Überlauf-, Unterlaufbedingung) überschritten werden. Der Programmierer braucht somit den Programmablauf weniger zu analysieren bzw. zu kontrollieren als bei Festkommazahlen. Außerdem ist die relative Darstellungsgenauigkeit in etwa konstant und unabhängig von der Größe der Zahl. Nachteile der Gleitkommazahlen sind der wesentlich höhere Verarbeitungsaufwand bei arithmetischen Operationen und die möglichen Fehler, die durch die Rundung auf die darstellbaren Werte bei der Durchführung arithmetischer Operationen entstehen. Eine Gleitkommazahl, die den Wert x darstellt, besteht aus der Mantisse mx und dem Exponenten ex zur Basis b. x = mx ∗ bex Für die folgenden Betrachtungen wollen wir die praktisch immer eingehaltene Bedingung annehmen, dass b mit der Basis der Darstellung der Mantisse übereinstimmt und dass für ex nur ganze Zahlen zugelassen sind. Ohne zusätzliche Bedingungen würde für den gleichen Wert x eine Reihe von Darstellungen (mx, ex) existieren. Die Darstellung wird erst dann eindeutig, wenn der Wertebereich der Mantisse beschränkt wird. Wir definieren eine normierte (normalisierte) Darstellung: x = vx ∗ mxnorm ∗ bk ∗bex {z } | m d xnorm 3 (0.1) Dabei stellt mxnorm die positive normalisierte Mantisse dar, vx das Vorzeichen (+1, −1) und k eine ganzzahlige Konstante. Bei der Darstellung der normalisierten Mantisse durch eine r-stellige b-näre Zahl eignet sich die Normalisierungsbedingung 1 1 ≤ mxnorm ≤ 1 − r < 1 b b am Besten. Damit ist das Komma der normalisierten Mantisse vor der Ziffer mit dem höchsten Wert vereinbart. Die kleinste normalisierte Mantisse wird dann durch .10...0 und die größte durch .(b−1)(b−1)...(b−1) dargestellt. Die normalisierte Mantisse ist also daran zu erkennen, dass die erste Ziffer hinter dem Komma 6= 0 ist. Alle Darstellungen, die mit 0 hinter dem Komma beginnen, sind verboten und damit redundant. Bei der 1 Basis b = 2 ist die Hälfte, bei b = 16 sind 16 aller möglichen Darstellungen redundant. k Die Konstante b bewertet die normalisierte Mantisse und definiert damit eine andere Kommastellung für die Mantisse m d xnorm . Für die Realisierung von arithmetischen Operationen auf Gleitkommazahlen ist es am günstigsten, k = 0 zu wählen. Wenn k = r gewählt wird, ist die Mantisse m d xnorm immer eine ganze Zahl. Wenn k = 1 gewählt wird (IEEE754-32-Bit-Gleitkommmaformat, siehe Abschnitt 0.2.2), dann liegt sie zwischen 1 und 2. Für die Darstellung der Mantisse wird vorzugsweise die Vorzeichen-BetragDarstellung benutzt. Dabei ist das Vorzeichenbit vx = o2 für x ≥ 0 (vx = +1) oder vx = l für x ≤ 0 (vx = −1). Diese Darstellung ist insbesondere für die Multiplikation und Division von Vorteil. Für den ganzzahligen Exponenten wird ein Wertebereich von exmin bis exmax definiert, wobei meist exmax = −exmin definiert wird. Für k = 0 ergibt sich damit für x ein Wertebereich von 1 bexmin −1 ≤ x ≤ bexmax ∗ (1 − r ). b Der Abstand zwischen zwei aufeinander folgenden x-Werten beträgt ∆x = 1 ∗ bex . br Wenn die Stelle mit dem niedrigsten Wert der Mantisse nicht sicher ist, dann schwankt der relative Fehler zwischen br 1 1 ≤ relativer Fehler ≤ r−1 . −1 b Die relative Darstellungsgenauigkeit von Gleitkommazahlen ist also in etwa konstant. Bei der Durchführung von arithmetischen Operationen kann der zulässige Wertebereich von x überschritten werden. Wird die obere Grenze überschritten, so spricht man von Überlauf (Overflow bzw. Exponentenüberlauf), wird die untere Grenze unterschritten, so spricht man von Unterlauf (Underflow bzw. Exponentenunterlauf). Für die Darstellung des Exponenten eignet sich die 1-Komplement- oder 2-Komplementdarstellung, da sie die Addition und Subtraktion der Exponenten unterstützt, die bei 2 Im folgenden wird o für eine binäre 0 stehen und l für eine binäre 1, dies wird eingeführt, um die Darstellung im Text unterscheiden zu können. 4 der Durchführung der Gleitkommaoperationen notwendig sind. Einen besonderen Vorteil bietet die Darstellung des Exponenten als so genannte Charakteristik (biased exponent). Sie ergibt sich aus der Abbildungsfunktion EX[n] = ex + 2n−1 . (Diese Darstellung unterscheidet sich von der 2-Komplementdarstellung nur dadurch, dass das Vorzeichenbit negiert ist; bei der Addition von zwei Charakteristiken muss das Vorzeichenbit anschließend negiert werden). Der Vorteil dieser Darstellung ist, dass die Größer/Kleiner-Relation von ex auch in der Darstellung EX erhalten bleibt und sich somit Gleitkommazahlen leichter vergleichen lassen. Zu diesem Zweck bringt man EX im linken Teil eines Maschinenwortes und die normalisierte Mantisse mxnorm im rechten Teil unter. Dadurch lassen sich positive Werte auf einmal miteinander vergleichen. Möchte man den Vergleich auch auf negative x-Werte ausdehnen, so fügt man für x > 0 linksseitig ein l-Bit an; für x < 0 negiert man die Darstellung und fügt ein o-Bit an (Abb. 0.2.1). x > 0: x < 0: x = 0: l o l EX EX o mxnorm mxnorm beliebig Abbildung 0.2.1: Günstige Gleitkommadarstellung Bei der normalisierten Darstellung mit endlich vielen Stellen ist es nicht möglich, die Null direkt zu kodieren. Die Null lässt sich z.B. durch ex = −∞, durch mxnorm = 0 oder durch ein zusätzliches Kennbit darstellen. Folgende Darstellungen der Null sind gebräuchlich, wobei EX = 0 dem Wert −2n−1 = exmin − 1 entspricht: 1. EX = 0, mxnorm beliebig 2. EX beliebig, mxnorm = 0 3. EX = 0, mxnorm = 0 Die erste Möglichkeit bietet den Vorteil, bei der Darstellung der normalisierten Mantissen ein Bit einzusparen, da Vorzeichenbit und 1. Stelle hinter dem Komma immer ungleich sind (1-Komplement) bzw. immer gleich bei der Darstellung nach Abb. 0.2.1. Manchmal werden auch zwei Darstellungen benutzt, die erste wird dann als sehr kleiner, nicht mehr darstellbarer Wert (unechte Null) betrachtet, die zweite oder dritte als “echte” Null. Die Wahl der Basis wirkt sich bei gleicher Bitanzahl für EX und mx wie folgt aus: Durch eine größere Basis wachsen der Darstellungsbereich, der Abstand zwischen zwei aufeinander folgenden Werten und der maximale relative Fehler exponentiell. Dafür sinkt die Wahrscheinlichkeit, das Ergebnis nach einer arithmetischen Operation normalisieren zu müssen. 0.2.2 IEEE754-32-Bit-Gleitkommmaformat Darstellung 5 ex 128 EX 255 = llll llll 127 126 .. . 254 = llll lllo 253 = llll llol 0 -1 .. . 127 = olll llll 126 = olll lllo -126 -127 1 = oooo oool 0 = oooo oooo Interpretation kein gültiger Exponent; zur Darstellung von ∞ Kontrollcodes gültige Exponenten für normalisierte Gleitkommazahlen kein gültiger Exponent; zur Darstellung von Null bzw. Kleiner Zahl Abbildung 0.2.2: Gültige und ungültige Exponenten Vx 1 EX 8 FX 23 Das Vorzeichenbit (Sign) ist Vx = ( l, für negative Zahlen o, für positive Zahlen. Die Charakteristik EX (biased exponent, bias = 127) ensteht durch Addition von 127 = 28−1 −1 auf den echten Exponenten ex (unbiased exponent, true exponent), siehe Tabelle Abb. 0.2.2: EX[8] ex = ex + 27 − 1 = ex + 127 = EX − 127 ,für ex = −126, ..., +126 ,für EX = 1, ..., 254 Die Mantisse M X = 1.F X wird auf Werte zwischen 1 und 2 normalisiert, genauer 1 ≤ M X ≤ 2 − 2−23 . Dargestellt werden nur die 23 Binärstellen hinter dem Komma (fraction F X), da die Stelle vor dem Komma immer gleich 1 ist. Bemerkung: Nach der obigen Notation (Gleichung 0.1, Seite 3) gilt M XIEEE = m d xnorm = mxnorm ∗ 21 . Der Wert der normalisierten Gleitkommazahl ergibt sich aus der Beziehung x = (−1)Vx ∗ 2EX−127 ∗ (1.F X) ( +2EX−127 ∗ (1.F X) für Vx = o = −2EX−127 ∗ (1.F X) für Vx = l Betragsmäßig größter und kleinster normalisierter Wert: xmax = 2127 ∗ (2 − 2−23 ) ≈ 3.4 ∗ 1038 xmin = 2−126 ∗ (1.0) ≈ 1.17 ∗ 10−38 6 Zahlenbeispiele S = +23.75 → o looo ooll olll lloo oooo oooo oooo ooo S = +1.484375 ∗ 24 = +1.484375 ∗ 2131−127 = (+, 131, 1.484375) = (o, looo ooll, l.olll lloo oooo oooo oooo ooo) = o looo ooll olll lloo oooo oooo oooo ooo S = l olll lllo lloo oooo oooo oooo oooo ooo → −0.875 S = (l, olll lllo, l.lloo oooo oooo oooo oooo ooo) = (−, 126, 1.75) = −1.75 ∗ 2126−127 = −1.75 ∗ 2−1 = −0.875 Weitere Interpretationen der Darstellung 1. Die Null Darstellung der positiven Null: (o, 0, 0) Darstellung der negativen Null: (l, 0, 0) 2. Kleine Zahl (denormalized number) Darstellung: (Vx , 0, 6= 0) Betrag: 0 < |x| < 2−126 Kleine Zahlen repräsentieren sehr kleine Werte, die kleiner als xmin und größer als Null sind. Der Wert ergibt sich zu x = (−1)Vx ∗ 2EX−126 ∗ (0.F X). 3. Große Zahl, ∞ Darstellung: (Vx , 255, 0) Betrag: |x| > xmax ∞ kann sowohl ein positives als auch ein negatives Vorzeichen besitzen. 4. Ungültige Zahl (Not a Number, NAN) Darstellung: (Vx , 255, 6= 0) Ungültige Zahlen werden als Kontrollcodes interpretiert. Entweder entstehen bestimmte Kontrollcodes bei der Ausführung unzulässiger Operationen (z.B. 0 ∗ ∞) oder sie werden dazu benutzt, Statuswerte durch eine Serie von Operationen zu schleusen. 7 5. Überlauf (Overflow) Überlauf kann bei der Addition, Multiplikation und Division auftreten, wenn nach dem Runden ein Ergebnis |x| > xmax entsteht. 6. Unterlauf (Underflow) Unterlauf kann bei der Addition, Multiplikation, Division und Reziprokwertbildung 1 x auftreten, wenn nach dem Runden ein Ergebnis 0 < |x| < xmin entsteht. Als Ergebnis wird entweder eine “Kleine Zahl” erzeugt oder ±0. 7. Besondere Operationen Besondere Operationen können für die Verarbeitung von ∞, kleinen Zahlen und durch die Unterscheidung von positiver und negativer Null definiert werden. 8. Rundung bei einem nicht darstellbaren Rest R Vier Rundungsarten stehen zur Auswahl: • Rundung zur nächsten darstellbaren Zahl: |x|, R → |x| + 1 für R ≥ 0.5 (M SB von R ist l) → |x| für R ≤ 0.5 (M SB von R ist o) • Rundung in Richtung +∞: +|x|, R → +|x| + 1 für R 6= 0 −|x|, R → −|x| • Rundung in Richtung −∞: +|x|, R → +|x| −|x|, R → −|x| − 1 für R 6= 0 • Rundung in Richtung 0: |x|, R → |x| Änderung des Standards IEEE754 Ebenso wollen wir hier an der Stelle auf die Veränderung des Standards hinweisen. Hierzu kann man auf der Webseite des IEEE Standards [IEE08a] nachschauen, um weitere Informationen zu erlangen. 0.2.3 IEEE754-64-Bit-Gleitkommmaformat Das IEEE754-64-Bit-Gleitkommaformat (Double) entspricht dem IEEE754-32-Bit-Gleitkommaformat (Single) in seiner Aufbaustruktur. Für das Vorzeichenbit Vx wird 1 Bit, für die Charakteristik werden 11 Bits und für die Mantisse werden 52 Bits benutzt. Die Darstellung wird wie folgt interpretiert: 1. Falls EX = 1, ..., 2046, dann wird eine normalisierte Zahl mit dem Wert x = (−1)Vx ∗ 2EX−1023 ∗ (1.F X) dargestellt. 2. Falls EX = 0 und F X = 0, dann ist x = (−1)Vx ∗ 0. 8 3. Falls EX = 0 und F X 6= 0, dann wird eine nicht normalisierte (kleine) Zahl mit dem Wert x = (−1)Vx ∗ 2EX−1022 ∗ (0.F X) dargestellt. 4. Falls EX = 2047 und F X = 0, dann ist x = (−1)Vx ∗ ∞. 5. Falls EX = 2047 und F X 6= 0, dann wird NAN dargestellt. Für noch höhere Ansprüche an die Rechengenauigkeit kann das IEEE754-Gleitkommaformat auf (1, ≥ 15, ≥ 63) Bits erweitert werden. 0.2.4 Umrechenmethoden Es gibt prinzipiell mehrere Methoden zwischen Dezimal und Gleitkommadarstellung abzubilden. Hier werden im folgenden nun ein paar vorgestellt (an dem Beispiel 42.375), um eine kleine Übersicht zu erhalten. Dezimal 42.375 Vx o EX looo oloo FX olol ooll oooo oooo oooo ooo Dezimal → Gleitkomma (an dem Beispiel von 42.375) Da die Dezimalzahl positiv ist, wird Vx = o gewählt (dies trifft auf alle Methoden zu). Methode 1: Berechnung von ex und vorbereiten der Mantissenkonvertierung. Normalisieren der Dezimalzahl, wobei ex die Anzahl der Shiftoperationen ist. Normalisierte Dezimalzahl = Dezimalzahl ∗ 2ex 42.375 21.1875 10.59375 5.296875 2.6484375 /2 → /2 → /2 → /2 → /2 → 21.1875 1 10.59375 2 5.296875 3 2.6484375 4 1.32421875 =: z 5 = ex ex = 5 ⇒ EX = ex + 127 = 132 : looo oloo Nun wird die Mantisse berechnet durch wiederholtes multiplizieren von z mit zwei, jedoch wird, jedes mal wenn eine Eins vor dem Komma steht, diese durch eine Null ersetzt und an die entsprechende Stelle in der Mantisse eine Eins eintragen, ansonsten eine Null. Das Verfahren terminiert, wenn z = 0 ist. Vorbereitung : 1.32421875 → 0.32421875 9 0.32421874 → ∗2 0.6484375 0 0.6484375 ∗2 → 1.296875 1 0.296875 ∗2 → 0.59375 0 0.59375 ∗2 → 1.1875 1 0.1875 ∗2 → 0.375 0 0.375 ∗2 → 0.75 0 0.75 ∗2 → 1.5 1 0.5 ∗2 1.0 1 → F X = olol ooll oooo oooo oooo ooo Nun zu Gleitkommaformat zusammen schreiben o looo oloo olol ooll oooo oooo oooo ooo. Methode 2: Umwandlung der Dezimalzahl in eine duale Festkommazahl ohne Vorzeichen. /2 42 → 21 Rest 0 /2 21 → 10 Rest 1 /2 10 → 5 Rest 0 /2 5 → 2 Rest 1 /2 2 → 1 Rest 0 /2 1 → 0 Rest 1 = lololo 0.375 → ∗2 0.75 0 0.75 ∗2 → 1.5 1 0.5 ∗2 1.0 1 = 0.oll → 42.375 = lololo.oll Normalisieren der Festkommazahl wobei ex = “Anzahl der Verschiebungen des Kommas ist”. lololo.oll → l.ololooll ⇒ ex = 5 ⇒ EX = ex + 127 = 132 : looo oloo Nun zu Gleitkommaformat zusammen schreiben o looo oloo olol ooll oooo oooo oooo ooo. Gleitkomma → Dezimal (an dem Beispiel von 42.375) Die Dezimalzahl muss positiv sein, da Vx = o ist (wäre Vx = l erhielten wir eine negative Zahl). Berechnung von ex: Nun muss man EX von der Zwei-Komplementdarstellung in eine natürliche Zahl umwandeln. Hierfür werden die herkömmlichen Verfahren zur Umwandlung verwendet, wie 10 z.B. die Summationsmethode. EX = 1 ∗ 27 + 1 ∗ 22 = 128 + 4 = 132 ⇒ ex = EX − 127 = 132 − 127 = 5 Methode 1: Nun wird die Mantisse aus F X berechnet, durch aufsummieren der einzelnen Zweierpotenzen. Man muss jedoch die 1.x bei der Mantisse beachten! M X = 1.0 + n X F X[k] ∗ 2−(k+1) wobei F X[0] das niederwertigste Bit darstellt. k=0 M X = 1.0 + (1 ∗ 2−2 + 1 ∗ 2−4 + 1 ∗ 2−7 + 1 ∗ 2−8 ) = 1.0 + 0.32421875 = 1.32421875 Dezimalzahl ist nun durch M X ∗ 2ex gegeben. Dezimalzahl = M X ∗ 2ex = 1.32421875 ∗ 25 = 42.375 Methode 2: Shiften der Mantisse (in Binärdarstellung), um die von ex angebenen Menge, daher wenn ex = 5 ist wird um um 5 Stellen nach links geshiftet, falls ex negativ ist wird nach rechts geshiftet. Jedoch darf man bei dieser Methode die implizite 1. vor der Mantisse nicht vergessen! ex=5 l.olol ooll oooo oooo oooo ooo −→ l olol o.oll oooo oooo oooo ooo Nun haben wir eine Festkommadarstellung erhalten und können diese nun direkt in die Dezimalzahl umwandeln. V orkommaanteil = 1 ∗ 25 + 1 ∗ 23 + 1 ∗ 2 ∗ 1 = 42 N achkommaanteil = 1 ∗ 2−2 + 1 ∗ 2−3 = 0.375 Dezimalzahl = V ork.anteil + N achk.anteil = 42.375 Applets zur Konvertierung 0.2.5 Operationen mit Gleitkommazahlen Um nochmal alle Umwandlungen selbst überprüfen zu können, hier nochmal ein paar Links zu Java-Applets für die Gleitkommazahl-Konvertierung • Der IEEE 754 Umrechner von Harald Schmidt [Sch08]: http://www.h-schmidt.net/FloatApplet/IEEE754de.html 11 • IEEE-754 Floating-Point Conversion von Quanfei Wen und Kevin J. Brewer [WB08]: http://babbage.cs.qc.edu/IEEE-754/Decimal.html • IEEE 754 Floating-Point Formats von Ron Mak [Mak08]: http://www.apropos-logic.com/nc/FPFormats.html Addition/Subtraktion von Gleitkommazahlen Im Gegensatz zur Addition von Festkommazahlen ist die Addition von Gleitkommazahlen wesentlich komplizierter, weil die Exponenten und Mantissen getrennt behandelt werden müssen. Gesucht ist die normalisierte Mantisse ms und der Exponent es der Summe s = x + y = ms ∗ bes = mx ∗ bex + my ∗ bey . Bevor die Addition der Mantissen vorgenommen werden kann, muss der kleinere Exponent an den größeren angepasst werden. Dazu muss die Mantisse, die zu dem kleineren Exponenten gehört, um so viele Stellen nach rechts geschoben werden, wie die Differenz der Exponenten beträgt. ( (mx + my ∗ b−(ex−ey) ) ∗ bex , ey ≤ ex ms ∗ bes = (my + mx ∗ b−(ey−ex) ) ∗ bey , ex ≤ ey Im Anschluss an die Mantissen-Addition wird die Summe meist normalisiert. Besitzt die (positive) Mantisse ms k führende Nullen, so wird die Operation ms es := := ms ∗ bk es − k “Linksschift um k Stellen” und “Exponent erniedrigen” durchgeführt. Beim Linksschift der Mantisse werden von rechts Nullen nachgezogen. Die Mantissen-Addition kann auch mit höherer Genauigkeit durchgeführt werden, so dass die Stellen, die beim Anpassen der Exponenten nach rechts geschiftet werden, nicht verloren gehen. Diese Stellen können dann beim Normalisieren/Runden nach der Mantissen-Addition wieder verwendet werden. Die Vermeidung bzw. Minimierung von Rundungsfehlern ist bei numerischen Berechnungen von großer Bedeutung. Die Subtraktion annähernd gleich großer Zahlen sollte möglichst vermieden werden (durch Umformulierung des Programms, z.B. x1 − x2 + x3 − x4 = (x1 + x3) − (x2 + x4), weil dabei führende Stellen ausgelöscht und beim anschließenden Normalisieren vorher nicht vorhandene Nullen nachgezogen werden. Das Erniedrigen der Exponenten beim Normalisieren kann das Unterschreiten des zulässigen Exponentenbereichs es ∈ {esmin : esmax } zur Folge haben. Das Ergebnis ist dann so klein geworden, dass es nicht mehr darstellbar, aber noch nicht = 0 ist. Das Ergebnis wird entweder als unechte Null (kleiner Wert) weitergeführt oder gleich der echten Null gesetzt. Die echte Null entsteht nur dann, wenn x = −y ist, weil dann die Summenmantisse = 0 wird. Die Null wird häufig durch (exmin − 1) und mx = 0 (IEEE754-32-Bit-Gleitkommmaformat, siehe Abschnitt 0.2.2) kodiert. Bei der Mantissen-Addition kann ein Mantissenüberlauf entstehen, d.h. |ms| ≥ 1. Es 12 wird also eigentlich eine Stelle mehr zur Darstellung benötigt. Durch einen Schift nach rechts mit Nachziehen der entstandenen Übertragsstelle wird die Mantisse normalisiert. Der Exponent muss dabei um 1 erhöht werden. Das gelingt aber nur, wenn der Exponent noch nicht seinen Maximalwert erreicht hat, anderenfalls muss die Exponentenüberlaufbedingung gesetzt werden. Beispiele Wir wollen hier noch ein paar Beispiele zu der Addition betrachten, die ein paar Grenzfälle darstellen sollen. Beispiel 1 3.5 + 5.375 X = o looo oooo lloo oooo oooo oooo oooo ooo : 3.5 Y = o looo oool olol looo oooo oooo oooo ooo : 5.375 Zuerst passt man beide Exponenten aneinander an, dafür muss man den kleineren Exponenten an den Grösseren angleichen. Da ex = 1 und ey = 2 ist, verändert man die Gleitkommazahl X. Diese ist dann, nach der Veränderung: X 0 = “o looo oool lllo oooo oooo oooo oooo ooo”. Man muss jedoch beachten, dass diese Schreibweise nicht ganz gültig ist, da es sich hierbei nicht um eine normalisierte Mantisse handelt, somit dürfte man nicht das Gleitkommaformat benutzen. Weiterhin ist zu beachten, dass bei dem Vorgang die implizite 1 vor dem Komma mitgeshiftet wird (das ist eine der häufigsten Fehlerquellen). Nach der Anpassung der Exponenten, kann man nun die Mantissen mit der gewöhnlichen Addition verrechnen. o . lllo oooo oooo oooo oooo ooo +l . olol looo oooo oooo oooo ooo = lo . ooll looo oooo oooo oooo ooo Wie man sieht ist in diesem Falle die resultierende Mantisse nicht normalisiert, daher ist eine Normalisierung notwendig. Die Mantisse wird nun nach rechts geshiftet und der Exponent der Summe um eins erhöht. lo.ooll looo oooo oooo oooo ooo → l.oool lloo oooo oooo oooo ooo vs = o, es = looo oolo, ms = oool lloo oooo oooo oooo ooo S = o looo oolo oool lloo oooo oooo oooo ooo : 8.875 Beispiel 2 −0.375 + 8.5 X = l olll llol looo oooo oooo oooo oooo ooo : −0.375 Y = o looo oolo oool oooo oooo oooo oooo ooo : 8.5 Hier hat man es indirekt mit einer Subtraktion zu tun, dafür ist ein wenig mehr Arbeit erforderlich. Man muss zuerst die beiden Exponenten vergleichen, denn der grössere Exponent wird das resultierende Vorzeichen bestimmen, daher vs = |ex| > |ey|?vx : vy. Passt man beide Exponenten aneinander an, achtet man auf das entstehende Vorzeichen. 13 Da ex = −2 und ey = 3 ist, verändert man die Gleitkommazahl X. Diese ist dann, nach der Veränderung: X 0 = “l looo oolo oooo lloo oooo oooo oooo oooo ooo”. Nach der Anpassung der Exponenten, kann man nun die Mantissen mit der gewöhnlichen Subtraktion verrechnen, hierbei wird immer die betragsmässig kleinere Gleitkommazahl von der größeren abgezogen. l . oool oooo oooo oooo oooo ooo //das Y −o . oooo lloo oooo oooo oooo ooo //das X 0 = l . oooo oloo oooo oooo oooo ooo In diesem Fall ist die resultierende Mantisse normalisiert, daher ist keine Normalisierung notwendig. vs = o, es = looo oolo, ms = oooo oloo oooo oooo oooo ooo S = o looo oolo oooo oloo oooo oooo oooo ooo : 8.125 Multiplikation von Gleitkommazahlen Die Multiplikation von Gleitkommazahlen ist im Vergleich zur Addition von Gleitkommazahlen einfach. Die Mantissen der beiden Operanden werden miteineinander multipliziert und die Exponenten zur Basis b werden unabhängig davon addiert. p = x ∗ y = mp ∗ bep = (mx ∗ bex ) ∗ (my ∗ bey ) = (mx ∗ my) ∗ bex+ey Geht man für mx und my von normalisierten Mantissen Produkt-Mantisse zwischen den Grenzen 1 b ≤ m < 1 aus, dann liegt die b−2 ≤ |mp| < 1. Das bedeutet, dass das Produkt nicht notwendigerweise normalisiert ist. Wenn die höchstwertige Ziffer der Mantisse gleich Null ist, dann muss die Mantisse um eine Stelle nach links geschoben werden, und der Exponent muss um Eins erniedrigt werden. Wird der Wertbereich des Exponenten nach oben oder unten überschritten, dann wird die Überlaufanzeige (Overflow) oder die Unterlaufanzeige (Underflow) gesetzt. Es folgt eine allgemeine, algorithmische Beschreibung für normalisierte Gleitkommazahlen, in der die Darstellungsform noch nicht festgelegt ist. Anweisungen, die in eckigen Klammern eingeschlossen und durch ein Komma getrennt sind, können parallel ausgeführt werden: i f ( ( x = 0) | | ( y = 0)) p := 0 ; else { mp := mx ∗ my ; i f ( 1 / b <= |mp| < 1 ) ” n o r m a l i s i e r t ” ep := ex + ey ; 14 e l s e ”bˆ( −2) <= |mp| < 1/b N o r m a l i s i e r e n ” { ep := ex + ey − 1 ; mp := mp ∗ b ; } i f ( ep > epmax ) ” E x p o n e n t e n ü b e r l a u f ” i f ( ep < epmin ) ” E x p o n e n t e n u n t e r l a u f , e v t l . p := 0” }. Wenn mx und my n-stellig sind, sollte die Multiplikation mindestens auf n+1 Stellen genau ausgeführt werden, damit beim Normalisieren eine gültige Ziffer nachgezogen werden kann. Als Darstellungsform für die Mantisse eignet sich am besten die Vorzeichen-BetragDarstellung oder Einskomplementdarstellung. Von der Benutzung der Zweikomplementdarstellung für die Mantisse ist abzuraten, da Sonderbehandlungen bei der Multiplikation und dem Normalisieren für die betragsmäßig größte negative Mantisse erforderlich werden. Beispiele Wir wollen hier noch ein paar Beispiele zu der Multiplikation betrachten, die ein paar Grenzfälle darstellen sollen. Beispiel 1 2.5 ∗ 1.25 X = o looo oooo oloo oooo oooo oooo oooo ooo : 2.5 Y = o olll llll oloo oooo oooo oooo oooo ooo : 1.25 Zuerst multipliziert man beide Mantissen miteinander, dafür verwendet man einen der vorgestellten Algorithmen aus der Vorlesung, die auf normalen Binärzahlen arbeiten, wie z.B. das serien-parallele Multiplikationswerk3 . l . oloo oooo oooo oooo oooo ooo ∗l . oloo oooo oooo oooo oooo ooo = l . lool oooo oooo oooo oooo ooo Nun addiert man beide Exponenten. looo oooo 3 + olll llll = llll llll − olll llll da 127 doppelt ist = looo oooo Dieser Algorithmus wird in der Vorlesung behandelt und kann auf einem weiteren Zusatzmaterial nachgelesen werden 15 Wie man sieht ist in diesem Falle die resultierende Mantisse normalisiert, daher ist keine Normalisierung notwendig. vs = o, es = looo oooo, ms = lool oooo oooo oooo oooo ooo S = o looo oooo lool oooo oooo oooo oooo ooo : 3.125 Beispiel 2 1.875 ∗ −29.5 X = o olll llll lllo oooo oooo oooo oooo ooo : 1.875 Y = l looo ooll llol looo oooo oooo oooo ooo : −29.5 Da beide Vorzeichen ungleich sind, folgt daraus dass vs = l sein muss. Zuerst multipliziert man beide Mantissen miteinander, dafür verwendet man einen der vorgestellten Algorithmen aus der Vorlesung, die auf normalen Binaerzahlen arbeiten, wie z.B. das serien-parallele Multiplikationswerk. l . lllo oooo oooo oooo oooo ooo ∗l . llol looo oooo oooo oooo ooo = ll . olll olol oooo oooo oooo ooo Nun addiert man beide Exponenten. olll llll + looo ooll = oooo oolo − olll llll da 127 doppelt ist = looo ooll Wie man sieht ist in diesem Falle die resultierende Mantisse nicht normalisiert, daher ist eine Normalisierung notwendig. Die Mantisse wird nun nach rechts geshiftet und der Exponent der Summe um eins erhöht. ll.olll olol oooo oooo oooo ooo → l.loll lolo looo oooo oooo ooo vs = l, es = looo oloo, ms = loll lolo looo oooo oooo ooo S = l looo oloo loll lolo looo oooo oooo ooo : −55.3125 16 Literaturverzeichnis [Hof93] Hoffmann, Rolf: Rechnerentwurf: Rechenwerke, Mikroprogrammierung, RISC. 3. Auflage. München : Oldenbourg, 1993. – ISBN 3–486–22174–4 [IEE08a] IEEE 754 Revision Work. http://grouper.ieee.org/groups/754/revision.html. 23. Juni 2008 Letzter Besuch: [IEE08b] IEEE 754: Standard for Binary Floating-Point Arithmetic. http://grouper.ieee.org/groups/754. Letzter Besuch: 23. Juni 2008 [Mak08] Mak, Ron. IEEE 754 Floating-Point Formats. http://www.apropos-logic.com/nc/FPFormats.html. such: 23. Juni 2008 2006. Letzter Be- [PH98] Patterson, David A. ; Hennessy, John L.: Computer Organization and Design: The Hardware/Software Interface. Second Edition. San Francisco, CA, USA : Morgan Kaufmann, 1998. – ISBN 1–55860–428–6 [Sch08] Schmidt, Harald. IEEE 754 Umrechner. http://www.h-schmidt.net/FloatApplet/IEEE754de.html. such: 23. Juni 2008 [WB08] Letzter Be- Wen, Quanfei ; Brewer, Kevin J. IEEE-754 Floating-Point Conversion. http://babbage.cs.qc.edu/IEEE-754/Decimal.html. 1998. Letzter Besuch: 23. Juni 2008 17