Einstieg in die Informatik mit Java Zahldarstellung und Rundungsfehler Gerd Bohlender Institut für Angewandte und Numerische Mathematik 1 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 2 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 3 / 34 Überblick In diesem Kapitel wird beschrieben, wie ganze Zahlen und Gleitkommazahlen dargestellt und bearbeitet werden. Ganze Zahlen Darstellung in Stellenwertsystem Gleitkommazahlen Zahldarstellung nach Standard IEEE 754 Fehlermöglichkeiten Mögliche Fehler die beim Rechnen mit ganzen Zahlen und Gleitkommazahlen auftreten können Rundungsfehler Rundungsfehler bei einzelnen Operationen und Auswirkungen in Programmen 4 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 5 / 34 Darstellung ganzer Zahlen, Stellenwertsystem Gegeben sei eine ganzzahlige Basis“ b > 1. Jede endliche ” ganze Zahl x kann durch ihre b-adische Entwicklung“ im ” Stellenwertsystem dargestellt werden x =± n X xi · bi = ±xn xn−1 . . . x2 x1 x0 i=0 Hierbei ist n ≥ 0 und xi eine der Ziffern 0 bis b − 1. Ist xn 6= 0, dann ist n + 1 die Stellenzahl zur Basis b. Neben dem Dezimalsystem (b = 10) werden in der Informatik häufig verwendet • das Dualsystem (Binärsystem, b = 2) • das Hexadezimalsystem (b = 16) • in älteren Anwendungen auch das Oktalsystem (b = 8) 6 / 34 Darstellung ganzer Zahlen, Ziffern Als Ziffern“ für Basen b > 10 werden Buchstaben verwendet: ” A = 10, B = 11, ..., F = 15, ..., Z = 35 Groß- und Kleinbuchstaben werden nicht unterschieden. Um Verwechslungen mit der Basis b zu vermeiden, verwenden wir hier vorzugsweise Großbuchstaben für die Ziffern. 7 / 34 Darstellung ganzer Zahlen, Basis Die Basis b wird in mathematischer Schreibweise als Index angehängt, z.B.: 10102 = 1010 , A016 = 16010 In Java wird bei Literalkonstanten die Basis durch den Präfix 0x für Hexadezimalzahlen, 0 für Oktalzahlen und ohne Präfix für Dezimalzahlen gekennzeichnet, z.B.: i n t i = 0123; / / O k t a l z a h l , d e z i m a l e r Wert 83 i n t j = 0x100 ; / / Hexadezimalzahl , Wert 256 i n t k = 0xAB ; / / 10∗16 + 11 = 171 8 / 34 Darstellung ganzer Zahlen, Basis Werte mit anderer Basis (i.a. im Bereich 2 bis 36) können in Java als String geschrieben werden. Die Umwandlung erfolgt durch Angabe der Basis als zweiter Parameter einer Umwandlungsfunktion. Umwandlung String in interne Darstellung mit Standardfunktion Integer.parseInt (wert, basis) i n t i = I n t e g e r . p a r s e I n t ( ” 100 ” , 1 6 ) ; / / 256 i n t j = I n t e g e r . p a r s e I n t ( ” 100 ” , 2 ) ; // 4 Umgekehrt Umwandlung interne Darstellung in String mit Standardfunktion Integer.toString (wert, basis) String s ; s = I n t e g e r . t o S t r i n g ( 1 6 0 , 1 6 ) ; / / e r g i b t ” A0 ” s = Integer . toString (9 , 2); / / e r g i b t ”1001” s = Integer . t o S t r i n g (35 , 36); / / ergibt ”Z” 9 / 34 Darstellung ganzer Zahlen, Umrechnung Umrechnung von Basis b in Dezimalsystem: Formel auswerten. ABC16 = A · 16 · 16 + B · 16 + C = 10 · 256 + 11 · 16 + 12 = 2560 + 176 + 12 = 274810 110012 = = = 1·2·2·2·2+1·2·2·2+0·2·2+0·2+1 16 + 8 + 1 2510 Multiplikationen sparen: Potenzen von b ausklammern! 567816 = ((5 · 16 + 6) · 16 + 7) · 16 + 8 = ((80 + 6) · 16 + 7) · 16 + 8 = (1376 + 7) · 16 + 8 = 22128 + 8 = 2213610 (allgemeines Verfahren: Hornerschema“) ” 10 / 34 Darstellung ganzer Zahlen, Umrechnung Umrechnung in Basis b: Ziffern abdividieren. Beispiel: i n t w = 100; // int b = 8; // String s = ” ” ; // while (w > 0 ) { / / int z = w % b; / / s = z + s; // w = w / b; // } / / e r g i b t s = ”144” Wert Basis am Anfang l e e r e r S t r i n g berechnet 4 , 4 , 1 n i e d e r s t e Z i f f e r bestimmen v o r s davor haengen von w a b d i v i d i e r e n Bei Basis b > 10 müssen ggf. Ziffern in die entsprechenden Darstellungen umgewandelt werden (Fallunterscheidung). Als alternativer Algorithmus können auch die höchsten Ziffern zuerst bestimmt werden durch Vergleich mit Potenzen bk . 11 / 34 Darstellung in festem Zahlformat, negative Zahlen In den Java-Datentypen byte, short, int, long wird die Basis b = 2 und eine feste Anzahl von n = 8, 16, 32, 64 Bits (binären Ziffern) eingesetzt. • 1 Bit Vorzeichen (0 = Plus, 1 = Minus) • n − 1 Bits für den Wert Negative Werte werden im Zweier-Komplement“ dargestellt; ” den Absolutbetrag einer negativen Zahl berechnet man: • alle Bits negieren (0 ↔ 1) • 1 addieren 12 / 34 Zahlbereich Mit n Bits ist der Bereich −bn−1 . . . bn−1 − 1 darstellbar. Ausnahme: char ist ein vorzeichenloser Datentyp. Typ byte short int long char n 8 16 32 64 16 min −27 −215 −231 −263 0 max 27 − 1 215 − 1 231 − 1 263 − 1 216 − 1 13 / 34 Beispiel: Positive und negative Bytes Beispiel byte Bits 00000000 00000001 00000010 00000011 ... 01111111 10000000 10000001 ... 11111110 11111111 Wert 0 1 2 3 ... 127 -128 -127 ... -2 -1 14 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 15 / 34 Überlauf, Beispiel byte Wird der darstellbare Bereich überschritten (z.B. bei byte Werte < −128 oder > 127), dann entsteht ein Überlauf. Achtung: Überlauf wird in Java nicht erkannt, es wird ohne Warnung weitergerechnet! Berechnetes Ergebnis = untere n Bits des korrekten Ergebnis, also ±k · bn Beispiel mit byte, berechnetes Ergebnis ist exaktes Ergebnis ±k · 256: Ausdruck 127 + 1 127 + 2 100 · 2 100 · 5 erwartet 128 129 200 500 berechnet -128 -127 -56 -12 Das gleiche Problem tritt bei den anderen ganzzahligen Datentypen short, int, long, char auf, beim Überschreiten der jeweiligen maximalen / minimalen darstellbaren Werte. 16 / 34 Explosion der Ariane 5 Rakete Überlauf kann zu katastrophalen Fehlern führen. Die europäische Rakete Ariane 5 wurde beim Erstflug am 4. Juni 1996 zerstört. Ablauf (siehe http://de.wikipedia.org/wiki/Ariane_V88): • Steuersoftware (in Ada geschrieben) für Ausrichtung der Inertialplattform, wichtig für Lagesteuerung • Umwandlung einer 64-Bit-Gleitkomma-Variable in eine vorzeichenbehaftete 16-Bit-Ganzzahl • Überlauf führt zu starker Neigung der Rakete nach 37 Sekunden Flug • Zerstörung der Rakete nach weiteren 3 Sekunden in 4 km Höhe • Verlust 290 Millionen Euro, keine Personenschäden Steuersoftware war von Ariane 4 übernommen, hat dort funktioniert. Aber in Ariane 5 traten größere Werte auf. 17 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 18 / 34 Darstellung reeller Zahlen Gegeben sei eine ganzzahlige Basis“ b > 1. Jede endliche ” reelle Zahl x kann durch ihre b-adische Entwicklung“ im ” Stellenwertsystem dargestellt werden x =± n X xi · bi = ±xn xn−1 . . . x2 x1 x0 .x−1 x−2 x−3 . . . i=−∞ Hierbei ist n ≥ 0 und xi eine der Ziffern 0 bis b − 1. Ist xn 6= 0, dann ist n + 1 die Stellenzahl vor dem Dezimalpunkt (Komma) zur Basis b. Die Stellenzahl hinter dem Dezimalpunkt ist i.a. unendlich. Die Darstellung ist i.a. nicht eindeutig, z.B. ist 1.000 . . . = 0.999 . . . Verwendete Basis ist meistens b = 10 oder b = 2. 19 / 34 Darstellung von Gleitkommazahlen Im Computer werden reelle Zahlen durch Gleitkommazahlen mit endlicher Genauigkeit approximiert. Darstellung durch eine Mantisse“ m der Form x0 .x1 x2 . . . xn mit Mantissenlänge n + 1 ” und einen Exponenten“ emin ≤ e ≤ emax: ” n X x =± xi · b−i · be = ±x0 .x1 x2 . . . xn · be i=0 Ist x0 6= 0, dann heißt die Zahl normalisiert“, sonst ” denormalisiert“. ” Die Java-Datentypen float bzw. double sind wie im IEEE-Standard 754 definiert (siehe http://de.wikipedia.org/wiki/IEEE_754). Basis b = 2, insgesamt 32 bzw. 64 Bits (binären Ziffern). • 1 Bit Vorzeichen (0 = Plus, 1 = Minus) • 8 bzw. 11 Bits für den Exponenten bei float bzw. double • restliche 23 bzw. 52 Bits für die Mantisse 20 / 34 Darstellung negativer Gleitkommazahlen, Details Negative Werte werden in Vorzeichen-Betragsdarstellung dargestellt; die Mantisse m enthält den Absolutbetrag der Zahl. Im Binärsystem ist bei normalisierten Zahlen die Ziffer x0 immer = 1, braucht also nicht gespeichert zu werden ( Hidden Bit“). ” Die Mantisse hat dann 24 bzw. 53 Bit bei float bzw. double Zum Exponenten wird intern ein Bias“ addiert, so dass er ≥ 0 ” wird. Zahlen mit dem maximalen Exponenten emax stellen ±∞ bzw. NaN (not a number) dar. Zahlen mit dem minimalen Exponenten emin stellen ±0 (es gilt −0.0 = +0.0 aber 1/(+0.0) = +∞, 1/(−0.0) = −∞) bzw. denormalisierte Zahlen dar (diese haben weniger gültige Stellen). 21 / 34 Überlauf Bei Gleitkommazahlen kann ebenfalls Überlauf auftreten, wenn die betragsgrößte darstellbare Zahl überschritten wird. Bei Überlauf wird kein unsinniges negatives Ergebnis eingesetzt (wie bei ganzen Zahlen) sondern der spezielle Wert +∞ bzw. −∞. Damit kann in der Regel normal weiter gerechnet werden. In manchen Fällen kann auch dies zu stark verfälschten Ergebnissen führen. Beispiel • x = 1e308 ist eine sehr große aber noch darstellbare Zahl • y = x + x führt zu Überlauf, Ergebnis +∞ • z = y − x liefert +∞, obwohl das Ergebnis 1e308 darstellbar wäre 22 / 34 Weitere Ausnahme-Situationen Weitere mögliche Ausnahme-Situationen und ihre übliche Behandlung: • Unterlauf (Exponent zu klein), es wird mit 0 weiter gerechnet • Division durch 0: es wird mit Unendlich weiter gerechnet • Illegale Operation (0/0, ∞ − ∞, usw.): es wird NaN (not a number) als Ersatzergebnis eingesetzt • Ungenaues Ergebnis: dies ist fast immer der Fall und wird ignoriert Java verwendet diese Standard-Behandlung. Im IEEE-Standard 754 sind auch andere Behandlungs-Varianten vorgesehen. 23 / 34 Gliederung 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler 24 / 34 Maschinengenauigkeit Zwei aufeinanderfolgende Gleitkommazahlen sind x = 1.000 . . . 00 x = 1.000 . . . 01 Die Differenz beschreibt die relative Genauigkeit des Zahlsystems: Maschinengenauigkeit“ oder ” Maschinen-Epsilon“ = 2−n bei n Nachkommastellen. ” Typ dezimal etwa float 2−23 1.2 · 10−7 double 2−52 2.2 · 10−16 Dies entspricht etwa 7 Dezimalstellen bei float und knapp 16 Dezimalstellen bei double. Gelegentlich wird auch die Hälfte dieses Werts als Maschinengenauigkeit verwendet (also 2−24 bei float und 2−53 bei double). 25 / 34 Rundung Ergebnisse von Eingabe, Operationen, Ausgabe sind in der Regel nicht mit der vorhandenen Maschinengenauigkeit darstellbar. Beispiele: • Summe 1 + 1e20 in double; benötigt etwa 63 Bit zur exakten Darstellung, double hat aber nur 53 Bit • Produkt zweier beliebiger Zahlen vom Typ double, ergibt einen Wert mit 2 · 53 = 106 Bit Mantisse; es sind aber nur 53 Bit in double für das Ergebnis vorhanden 26 / 34 Rundung Das exakte Ergebnis wird durch eine Rundung“ auf eine der ” beiden benachbarten Maschinenzahlen abgebildet. Rundungen nach IEEE-Standard 754: • Rundung nach unten (in Richtung −∞) • Rundung nach oben (in Richtung +∞) • Rundung durch Abschneiden (in Richtung 0) • Rundung zur nächstgelegenen Gleitkommazahl Liegt das Ergebnis einer Operation genau in der Mitte zwischen zwei Gleitkommazahlen, dann wird bei der Rundung zur nächstgelegenen Gleitkommazahl auf das Ergebnis mit gerader Endziffer gerundet. Java verwendet für float und double immer die Rundung zur nächstgelegenen Gleitkommazahl. 27 / 34 Rundungsfehler, Abschätzung Bezeichnet fl(x ◦ y ) die Gleitkomma-Auswertung einer Operation x ◦ y, dann gilt für den relativen Fehler |fl(x ◦ y) − (x ◦ y )| < |x ◦ y | bzw. bei Rundung zur nächstgelegenen Gleitkommazahl |fl(x ◦ y ) − (x ◦ y)| < /2 |x ◦ y | Also umgeformt fl(x ◦ y ) = (x ◦ y) · (1 + e) mit |e| < bzw. bei Rundung zur nächstgelegenen Gleitkommazahl fl(x ◦ y ) = (x ◦ y) · (1 + e) mit |e| < /2 28 / 34 Rundungsfehler, Abschätzung bei mehreren Operationen Die Rundungsfehler-Abschätzungen gelten nur für eine einzelne Operation! Warnung Es ist sehr schwierig, den Rundungsfehler nach mehreren Operationen abzuschätzen! Rundungsfehler nach k Operationen • bei Rundung zur nächstgelegenen Gleitkommazahl können sich Rundungsfehler z.T. gegeneinander aufheben, der relative Fehler ist dann < k · • in ungünstigen Fällen können Rundungsfehler sehr stark anwachsen, der relative Fehler ist dann >> k · • insbesondere bei Subtraktion von etwa gleich großen Werten: Genauigkeitsverlust durch Auslöschung“ gültiger ” Ziffern 29 / 34 Rundungsfehler, Auslöschung Beispiel (3-stellige Dezimalzahlen): 1.23 als Näherung für 1.23456, 3 Stellen genau 1.22 als Näherung für 1.21613, 3 Stellen genau 0.01 Differenz dieser Werte, max. 1 Stelle genau 1e − 2 im Gleitkommaformat Die exakte Differenz wäre 0.01843, also 1.84e − 2 im Gleitkommaformat. Durch katastrophale Auslöschung ist das Ergebnis extrem ungenau (relativer Fehler etwa 80 Prozent statt erwarteten 1 Prozent). Beispiel (double): fl(1 + 1020 − 1020 ) = 1020 − 1020 = 0 30 / 34 Gültigkeit mathematischer Eigenschaften Bei Gleitkomma-Rechnung versagen viele mathematische Regeln wie Assoziativität, Distributivität, usw. Es gilt z.B. 1 = fl(1 + (1020 − 1020 )) 6= fl((1 + 1020 ) − 1020 ) = 0 Bei Gleitkomma-Rechnung gelten Konvergenzaussagen (Folge oder Reihe konvergiert gegen Grenzwert) nicht mehr. • numerisch berechnete Folge kann ab einem Index k konstant bleiben • oder sogar divergieren durch Einfluss von Rundungsfehlern 31 / 34 Rundungsfehler, Beispiel Berechne die einfache Formel p2 − 2 · q 2 für p = 665857.0 und q = 470832.0 Das berechnete Ergebnis mit float ist 0.0 Das exakte Ergebnis ist 1.0. In diesem Fall liefert double das exakte Ergebnis. Quadriert man die Formel, so erhält man nach der binomischen Formel p4 − 4 · p2 · q 2 + 4 · q 4 Mit den gleichen Werten von p und q ist das exakte Ergebnis offenbar 1, das berechnete Ergebnis mit double ist −3.3554432E7, also falsches Vorzeichen und 7 Zehnerpotenzen zu groß (Fehler über 3 000 000 000 Prozent)! Nach nur 13 arithmetischen Operationen! 32 / 34 Rundungsfehler, Beispiel Patriot-Rakete Rechenfehler in einer Patriot-Rakete der US-Armee, die zur Abwehr von Scud-Raketen dient • Zeit wird in der Rakete als float Wert mit 32 Bit Genauigkeit abgespeichert • Uhr zählt mit Zehntelsekunden • Rechenfehler akkumulieren sich über mehrere Stunden • zum Einsatzzeitpunkt war die Zeitabweichung 0.34 Sekunden • die angreifende irakische Scud-Rakete fliegt mit 6000 km/h • 0.34 Sekunden entspricht etwa 500 m Weg • daher wurde die Abfangrakete nicht gestartet • Resultat: 28 Tote, 100 Verletzte Weitere Beispiele für Rechenfehler mit katastrophalen Auswirkungen siehe http://www.dradio.de/aktuell/791580/ 33 / 34 Genauigkeit vs. Sicherheit Genauigkeit = Abweichung des berechneten Wertes vom exakten Wert Sicherheit / Verifikation des Ergebnisses = strikter Beweis, dass Ergebnis existiert und maximal um x Prozent vom berechneten abweicht Dies sind unabhängige Paradigmen, sei z.B. das exakte Ergebnis 1 • das berechnete Ergebnis 1.00000000000001 ist extrem genau, aber eventuell unsicher / nicht verifiziert, wenn keine Fehlerabschätzung bekannt ist • das berechnete Ergebnis 2 ist sehr ungenau, aber eventuell ist es sicher / verifiziert, falls eine rigorose Fehlerabschätzung existiert 34 / 34