Grenzen der Genauigkeit

Grenzen der Genauigkeit in der praktischen Informatik

Mit einem Experiment wird die Rechen-Genauigkeit Live gemessen:
Man bestimmt die kleinste Änderung einer Zahl, die für den PC gerade noch berechenbar ist.



Genauigkeit mit Tabellen-Kalkulation

 
A
B
C
D
1
n
z1
z2
z2-z1
2
1
=ZUFALLSZAHL()*10
=B2*(1+10^(-A2))
=C2-B2
3
=A2+1
=$B$2
=B3*(1+10^(-A3))
=C3-B3
4
=A3+1
=$B$2
=B4*(1+10^(-A4))
=C4-B4
 
⇓⇓
⇓⇓
⇓⇓
⇓⇓
21
=A20+1
=$B$2
=B21*(1+10^(-A21))
=C21-B21
Dieses Kapitel zeigt ein einfaches Experiment, mit dem man die Grenze der Rechen-Genauigkeit jedes Computers selbst messen kann.

Es funktioniert mit jedem Standard → Kalkulations-Programm, z.B. mit
LibreOffice-Calc, MS-Excel, OpenOffice-Calc

Im ↓ Live-Kapitel dieser Seite sehen sie das Ergebnis des Programms, hier allerdings mit Javascript berechnet.


Anwendung: Mit Klick auf Taste F9 wird das Experiment mit einer neuen Zufallszahl in Zelle B2 wiederholt.


Funktion

• In Spalte B wird eine Zufallszahl z1 vorgegeben (Neu mit Taste F9).

• In Spalte C wird die Zahl z2 berechnet, deren Wert etwas größer ist als z1
In der ersten Zeile ist z2 um 1/10 größer als z1, in der 2. Zeile um 1/100, in der 3.Zeile um 1/1000 usw.

• In Spalte D wird die Differenz der beiden Zahlen z2-z1 berechnet. Dieser Wert solte mit jeder weiteren Zeile immer kleiner werden, jedoch stets >0 bleiben.


Auswertung der Ergebnisse

Verfeinerte Experimente

Es ist aufschlussreich, das Experiment mit anderen Werten zu wiederholen, d.h. mit anderen Vorgaben in Zelle B2, z.B.
=ZUFALLSZAHL()/1000
=ZUFALLSZAHL()*1000

Die Ergebnisse zeigen, dass der Fehler unabhängig (!) vom Zahlenwert immer nach 14-15 Schritten auftritt.

Der kleinste unterscheidbare Wert ändert sich jedoch mit dem Wert der Zahl. Wenn man damit experimentiert, dann findet man, dass diese Grenze für jede Zahl z1 bei ca. z1*3E-15 liegt.

• In diesem Experiment werden nur ausgewählte relative Differenzen (1/10, 1/100, ...) untersucht. Für genauere Ergebnisse müsste man die Abstufung verfeinern (z.B. auf 1/10, 9/100, 8/100, 7/100, ...), Daher muss die 'wahre Genauigkeit' noch etwas besser sein als hier berechnet.



• Beispiel: Die Entfernung Erde-Sonne beträgt ca. 150 Mio km. Die numerische Genauigkeit dieses Zahlenwerts beträgt
1.5E9 Meter * 2-53 = 1.66E-5 Meter = 0.017mm



Faustregel: Die Genauigkeit der Differenz nimmt um den dekadischen Logarithmus des relativen Differenz ab.
Für dieses Beispiel:
Genauigkeit der Ausgangs-Werte (z1,z2): 16 Stellen
Verringerung: log10(reldif) = -6
Genauigkeit der Differenz: 16 - 6 = 10 Stellen

• Daraus kann man folgern, dass Rechnungen mit relativen Differenzen von <=1E‑12 nur mehr Richtwerte liefern, solche mit <=1E‑14 eher zufällige Ergebnisse.

Genauigkeit mit Taschenrechner


Live-Genauigkeit mit Javascript


Erklärung

• Schon in den ersten Zeilen der Spalte C zeigt sich, dass nur die ersten 15-16 Ziffern genau berechnet werden, und alle folgenden Ziffern offenbar zufällige Werte enthalten.

• Ungefähr ab 10..n..12 wird die Differenz in Spalte D nicht mehr exakt berechnet. Man nähert sich hier bereits der Grenze der Genauigkeit.

• Spätestens ab n>=16 ergibt die Berechnung der Differenz einen offensichtlichen Fehler:
Die Multiplikation der Zahl z1 mit dem Faktor 1+10^(‑n) ist nicht mehr möglich und/oder die Differenz ergibt =0
In diesem Fall liegt die 'wahre' Differenz unter der Grenze der Genauigkeit und kann nicht mehr berechnet werden.



var eps = Number.EPSILON
alert('Epsilon = '+eps);
// console.log('Epsilon = '+eps);
Live-Ergebnis:
Epsilon = ?



var safe_min = Number.MIN_SAFE_INTEGER
var safe_max = Number.MAX_SAFE_INTEGER
i = Math.pow(2,?);
if(Number.isSafeInteger(i)) {txt='sicher';}
else{txt='nicht sicher';}
Live-Ergebnisse:
Kleinste SAFE_INTEGER Zahl = ?
Größte SAFE_INTEGER Zahl   = +?
Mantisse-Bits = ?
Die Ganze Zahl 2? ist ? sicher.
Die Ganze Zahl 2?-1 ist ? sicher.
Die Ganze Zahl 2? ist ? sicher.
Die Ganze Zahl 2?+1 ist ? sicher.

Genauigkeit für Fortgeschrittene

 
A
B
C
D
E
F
1
n
z1
z2
z2-z1
(z2-z1)/z1
2^(-n)
2
1
=10^(ZUFALLSZAHL()*24-12)
=B2+B2*2^(-A2)
=C2-B2
=D2/B2
2^(-A2)
3
=A2+1
=$B$2
=B3+B3*2^(-A3)
=C3-B3
=D3/B3
2^(-A3)
4
=A3+1
=$B$2
=B4+B4*2^(-A4)
=C4-B4
=D4/B4
2^(-A4)
 
⇓⇓
⇓⇓
⇓⇓
⇓⇓
⇓⇓
⇓⇓
56
=A55+1
=$B$2
=B56+B56*2^(-A56)
=C56-B56
=D56/B56
2^(-A56)

Binäre Experimente

Computer verwenden intern das Binäre Zahlensystem.
Mit kleinen Änderungen des Programms erhält man Ergebnisse, die für Informatik-Insider bessere Aussagen liefern.


Folgerung

Gleitkomma-Zahlen werden offenbar in relativer Form gespeichert, d.h. als Mantisse und Exponent, so wie im 'Wissenschaftlichen' Zahlen-Format. Intern werden allerdings binäre Mantissen und Exponenten verwendet.

Die binäre Mantisse muss mindestens 50 Bit umfassen.

Die Größe des binären E xponenten kann man schätzen: Daten werden nur in ganzen Bytes gespeichert: Die nächste sinnvolle Byte- und Wort-Grenze liegt bei 8 Byte = 64 Bit. Wenn diese Annahme zutrifft, dann bleiben für Vorzeichen und Exponent 14 Bit.

Mit dem ähnlichen Beispiel → Numerische Grenzwerte kann man die Größe des Exponenten experimentell bestimmen.



Anmerkungen zum Variablen-Typ 'Double Precision':
• Die theoretisch größte darstellbare Zahl (2^1024)-1 ist in der Praxis nicht mehr berechenbar. Daher ist darunter eine praktisch verwendbare Formel angegeben.

• Die höchste Ziffer einer binären Mantisse ist immer 1, sie wird daher nicht gespeichert, jedoch zum Rechnen verwendet. Daher werden nur 52 Bit der binären Mantisse gespeichert, das 53. (Hidden) Bit verdoppelt jedoch die Genauigkeit gegenüber 52 Bit.

• Der Exponent ist als binäres '2er-Komplement' gespeichert. Daher kann er nur Werte -1022...+1023 annehmen. Die kleinste Zahl ist daher +- 2^(-1022)

Wikipedia: Single Precision, Double Precision, Gleitkomma-Zahlen, Standard IEEE-754, Wissenschaftliches Zahlenformat, Mantisse, Binärsystem, 2er-Komplement


Rechnen mit Zeichenketten

Alle modernen Programmiersprachen bieten Module zum Rechnen mit beliebiger Genauigkeit.
Jede Zahl wird als Zeichenkette (Text, String) von Ziffern gespeichert, z.B. als "1234"; und nicht wie sonst als 1234
Rechnungen werden schrittweise mit jeder einzelnen Ziffer ausgeführt, so wie man es in der Grundschule lernt und mit Bleistift & Papier noch immer macht.

Das verlangsamt alle Rechnungen um mehrere Größenordnungen, erlaubt aber fast beliebige Genauigkeit (Je nach String-Typ mindestens 2000 Ziffern meist 65000 Ziffern).
• Das Beispiel zur → Berechnung der Kreiszahl Pi demonstriert Live die Anwendung mit der Programmiersprache PHP und (falls vom Web-Provider angeboten) mit Perl.

Im technisch-wissenschaftlichen Bereich wird → Perl bevorzugt: Damit kann man u.a. in wenigen Minuten ein Programm schreiben, welches eine Aufgabe mit beliebiger Genauigkeit berechnet.