1 / 34 Einstieg in die Informatik mit Java Zahldarstellung und Rundungsfehler Gerd Bohlender Institut für Angewandte und Numerische Mathematik
Gliederung 2 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
Gliederung 3 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
Ü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 5 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
6 / 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 i b i = ±x n x n 1... x 2 x 1 x 0 i=0 Hierbei ist n 0 und x i eine der Ziffern 0 bis b 1. Ist x n 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)
7 / 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.
Darstellung ganzer Zahlen, Basis 8 / 34 Die Basis b wird in mathematischer Schreibweise als Index angehängt, z.b.: 1010 2 = 10 10, A0 16 = 160 10 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; / / Oktalzahl, dezimaler Wert 83 i n t j = 0x100 ; / / Hexadezimalzahl, Wert 256 i n t k = 0xAB ; / / 10 16 + 11 = 171
Darstellung ganzer Zahlen, Basis 9 / 34 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) S t r i n g s ; s = I n t e g e r. t o S t r i n g (160, 1 6 ) ; / / e r g i b t A0 s = I n t e g e r. t o S t r i n g ( 9, 2 ) ; / / e r g i b t 1001 s = I n t e g e r. t o S t r i n g (35, 3 6 ) ; / / e r g i b t Z
Darstellung ganzer Zahlen, Umrechnung 10 / 34 Umrechnung von Basis b in Dezimalsystem: Formel auswerten. ABC 16 = A 16 16 + B 16 + C = 10 256 + 11 16 + 12 = 2560 + 176 + 12 = 2748 10 11001 2 = 1 2 2 2 2 + 1 2 2 2 + 0 2 2 + 0 2 + 1 = 16 + 8 + 1 = 25 10 Multiplikationen sparen: Potenzen von b ausklammern! 5678 16 = ((5 16 + 6) 16 + 7) 16 + 8 = ((80 + 6) 16 + 7) 16 + 8 = (1376 + 7) 16 + 8 = 22128 + 8 = 22136 10 (allgemeines Verfahren: Hornerschema )
Darstellung ganzer Zahlen, Umrechnung 11 / 34 Umrechnung in Basis b: Ziffern abdividieren. Beispiel: i n t w = 100; / / Wert i n t b = 8; / / Basis S t r i n g s = ; / / am Anfang l e e r e r S t r i n g while (w > 0) { / / berechnet 4, 4, 1 i n t z = w % b ; / / n i e d e r s t e Z i f f e r bestimmen s = z + s ; / / vor s davor haengen w = w / b ; / / von w a b d i v i d i e r e n } / / e r g i b t s = 144 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 b k.
12 / 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
Zahlbereich 13 / 34 Mit n Bits ist der Bereich b n 1... b n 1 1 darstellbar. Ausnahme: char ist ein vorzeichenloser Datentyp. Typ n min max byte 8 2 7 2 7 1 short 16 2 15 2 15 1 int 32 2 31 2 31 1 long 64 2 63 2 63 1 char 16 0 2 16 1
Beispiel: Positive und negative Bytes 14 / 34 Beispiel byte Bits Wert 00000000 0 00000001 1 00000010 2 00000011 3...... 01111111 127 10000000-128 10000001-127...... 11111110-2 11111111-1
Gliederung 15 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
Ü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 b n Beispiel mit byte, berechnetes Ergebnis ist exaktes Ergebnis ±k 256: Ausdruck erwartet berechnet 127 + 1 128-128 127 + 2 129-127 100 2 200-56 100 5 500-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
17 / 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.
Gliederung 18 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
Darstellung reeller Zahlen 19 / 34 Gegeben sei eine ganzzahlige Basis b > 1. Jede endliche reelle Zahl x kann durch ihre b-adische Entwicklung im Stellenwertsystem dargestellt werden x = ± n i= x i b i = ±x n x n 1... x 2 x 1 x 0.x 1 x 2 x 3... Hierbei ist n 0 und x i eine der Ziffern 0 bis b 1. Ist x n 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.
Darstellung von Gleitkommazahlen Im Computer werden reelle Zahlen durch Gleitkommazahlen mit endlicher Genauigkeit approximiert. Darstellung durch eine Mantisse m der Form x 0.x 1 x 2... x n mit Mantissenlänge n + 1 und einen Exponenten emin e emax: x = ± n x i b i b e = ±x 0.x 1 x 2... x n b e i=0 Ist x 0 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 21 / 34 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 x 0 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).
22 / 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
23 / 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.
Gliederung 24 / 34 1 Überblick 2 Darstellung ganzer Zahlen, Stellenwertsystem 3 Überlauf 4 Darstellung von Gleitkommazahlen 5 Rundungsfehler
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
26 / 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
27 / 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.
Rundungsfehler, Abschätzung 28 / 34 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) x y < ɛ/2 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
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 30 / 34 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 + 10 20 10 20 ) = 10 20 10 20 = 0
31 / 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 + (10 20 10 20 )) fl((1 + 10 20 ) 10 20 ) = 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
Rundungsfehler, Beispiel 32 / 34 Berechne die einfache Formel p 2 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 p 4 4 p 2 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!
33 / 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/
34 / 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