Seite 1 von 1

Grenzen von Computerzahlen und Runden

Verfasst: Sonntag 3. November 2019, 11:04
von Stefsn
Hey Leute,

ich bin heute mal auf die witzige Idee gekommen, nach der kleinsten Computerzahl zu schauen, die mir Python anbietet. Dafür habe ich folgenden Code genommen:

Code: Alles auswählen

def min_comp_num():
    eps1 = 1
    steps = 0
    while eps1 / 2 > 0:
        steps += 1
        eps1 = eps1 / 2
    return eps1, steps

def min_plus_one():
    eps2 = 1
    steps = 0
    val = 0
    while 1 + eps2 / 2 > 1:
        steps += 1
        val = 1 + eps2 / 2
        eps2 = eps2 / 2
    return val, eps2, steps

def main():

    mini1, steps1 = min_comp_num()
    val, mini2, steps2 = min_plus_one()
    print('First minimum: ', mini1, 'Steps: ', steps1)
    print('Second minimum: ', val, mini2, 'Steps: ', steps2)

if __name__ == "__main__":
    main()

Interessanterweise kommt dabei folgendes Ergebnis heraus:

First minimum: 5e-324 Steps: 1074
Second minimum: 1.0000000000000002 2.220446049250313e-16 Steps: 52

Was mir auffällt, wenn ich mich immer weiter der Null annähere, dann habe ich eine Genauigkeit von 5e-324. Wenn ich dasselbe Prinzip aber mit plus 1 anwende, dann verringert sich die Genauigkeit auf "nur" 16 Nachkommastellen.

Woran liegt das? Ich habe mir diesen Wikipedia Artikel angelesen, aber bin daraus irgendwie nicht ganz schlau geworden. Und gibt es eine Möglichkeit in Python die Genauigkeit einer Rechnung forciert zu erhöhen?

https://de.wikipedia.org/wiki/Gleitkomm ... kommazahl)

Re: Grenzen von Computerzahlen und Runden

Verfasst: Sonntag 3. November 2019, 14:44
von __blackjack__
@Stefsn: Je kleiner eine Gleitkommazahl um so kleiner ist auch der Abstand zu den nächsten Nachbarn die man als Gleitkommazahl darstellen kann. Die Anzahl der signifikanten Dezimalstellen bleibt dabei aber immer gleich. Bei 1 sind es 16, bei 0 aber auch, nur das davor alle Nachkommastellen 0 sind.

Mit der zweiten Funktion hast Du übrigens `sys.float_info.epsilon` ausgerechnet. Falls Dir die Informationen in der Dokumentation dazu vielleicht weiterhelfen.

Man kann auf Kosten der Rechengeschwindigkeit mit Brüchen (`fractions`-Modul) oder Dezimalbrüchen mit beliebiger Genauigkeit (`decimal`-Modul) rechnen. Es gibt auch eine Python Anbindung an `libgmp`. Und mit `sympy` kann man auch symbolisch rechnen und damit eventuell den Kontakt mit der Ungenauigkeit von IEEE-Gleitkommazahlen weiter ”nach hinten” schieben.

Re: Grenzen von Computerzahlen und Runden

Verfasst: Sonntag 3. November 2019, 22:40
von Stefsn
Tut mir leid für die späte Antwort. :)

Das verwirrt mich ein wenig. Weil bei der „Null“ scheint es doch 324 Stellen zu geben. Ich habe es auch mit höheren Integers gemacht und da kommen weiterhin 16 Signifikante Stellen heraus.

Und mit dem Abstand, dass habe ich glaube ich verstanden. Also je näher man der null kommt, desto „dichter“ ist die Zahlenverteilung, korrekt? Das hat dann ja mit der eigentlichen Binärzahldarstellung zu tun?

Würdest du sagen, wenn ich das gleiche Experiment nicht mit 1 + eps2 sonder 0.1 + eps2 mache, dass ich dann mehr signifikante Stellen bekomme?

Danke für deine Hilfe. :)
Und gibt es auch eine Möglichkeit diese Stellen zu errechnen? Ja

Re: Grenzen von Computerzahlen und Runden

Verfasst: Montag 4. November 2019, 03:17
von __blackjack__
@Stefsn: Bei der „Null“, also dem Ergebnis 5e-324 gibt es zwar 324 Stellen nach dem Komma, von denen sind aber 323 eine 0 und die allermeisten können auch nichts anderes als 0 sein, denn es gibt halt nur Bits für ca. 16 signifikante Dezimalstellen in „IEEE double presicion“. Die Frage ist nicht wie viele Stellen nach (oder vor) dem Komma stehen, sondern wie viele davon tatsächlich den Wert ausmachen (können).

Das die Abstände zwischen kleinen als Gleikommazahlen darstellbaren Zahlen kleiner sind als zwischen grossen hat nichts mit der *Binär*darstellung zu tun, sondern mit der Gleitkommadarstellung allgemein. Das wäre auch so wenn man Mantisse und Exponent in Dezimaldarstellung mit endlicher Genauigkeit darstellen würde.

Die Mantisse hat bei „IEEE double precision“ 53 Bits (eins davon ist implizit immer 1) für die Mantisse — es ist egal ob Du da nichts, 1 oder 0.1 addierst, es werden nicht mehr Bits und damit auch nicht mehr signifikante Stellen. Binär gesehen sind es genau 53 signifikante Binärstellen. Das in Dezimalstellen umgerechnet sind eben knapp 16:

Code: Alles auswählen

In [165]: 53 * math.log10(2)                                                    
Out[165]: 15.954589770191003

Re: Grenzen von Computerzahlen und Runden

Verfasst: Montag 4. November 2019, 10:01
von __deets__
Weil wir es gerade neulich beruflich hatten: deine Aussage es ist immer ein implizites gesetztes 1 bit stimmt so nicht. Es gibt noch denormalisierte Nummern. Da wird der exponent 0 gesetzt und ist dann implizit -126 bz -1022. Und dann sind die Bits der mantisse ohne führende 1. Dadurch kommt man auf noch kleinere epsilon. Allerdings unterstützen die Rechen Werke in der CPU das schlecht, und man hat Performance Einbrüche. Weswegen das deaktiviert werden kann.

Re: Grenzen von Computerzahlen und Runden

Verfasst: Montag 4. November 2019, 10:15
von Sirius3
Deshalb ist die kleinste Zahl auch 5e-324, und nicht 2e−308. Die weiteren 16 Nullstellen kommen daher, dass die Nullen explizit in den 52-Bit Mantisse stehen. 5e-324 hat dann (neben dem Exponenten) auch nur noch genau 1 Bit an Information.