Einstieg in die Informatik mit Java - KIT

Werbung
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
Herunterladen