Dass dies funktioniert, ist überhaupt nicht trivial! Es ist eine Eigenschaft der IEEE-Gleitkommadarstellung, dass int∘floor = ⌊⋅⌋ ist, wenn die Größe der fraglichen Zahlen klein genug ist, aber unterschiedliche Darstellungen möglich sind, wenn int (floor (2.3)) 1 sein könnte.
Dieser Beitrag erklärt, warum es in diesem Bereich funktioniert .
In einem Double können Sie problemlos 32-Bit-Ganzzahlen darstellen. Es kann keine Rundungsprobleme geben. Genauer gesagt können Doubles alle ganzen Zahlen zwischen und einschließlich 2 53 und -2 53 darstellen .
Kurze Erklärung : Ein Double kann bis zu 53 Binärziffern speichern. Wenn Sie mehr benötigen, wird die Zahl rechts mit Nullen aufgefüllt.
Daraus folgt, dass 53 Einsen die größte Zahl sind, die ohne Auffüllen gespeichert werden kann. Natürlich können alle (ganzzahligen) Zahlen, die weniger Ziffern erfordern, genau gespeichert werden.
Addiert man eins zu 111 (weggelassen) 111 (53 Einsen) ergibt 100 ... 000 (53 Nullen). Wie wir wissen, können wir 53 Ziffern speichern, was die Nullpunktauffüllung ganz rechts ergibt.
Hier kommt 2 53 her .
Weitere Details: Wir müssen überlegen, wie IEEE-754-Gleitkomma funktioniert.
1 bit 11 / 8 52 / 23 # bits double/single precision
[ sign | exponent | mantissa ]
Die Anzahl wird dann wie folgt berechnet (ausgenommen hier irrelevante Sonderfälle):
-1 Vorzeichen × 1. Mantisse × 2 Exponent - Vorspannung
wobei Bias = 2 Exponent - 1 - 1 ist , dh 1023 und 127 für doppelte / einfache Genauigkeit.
Wenn man weiß, dass das Multiplizieren mit 2 X einfach alle Bits X nach links verschiebt, ist es leicht zu erkennen, dass jede Ganzzahl alle Bits in der Mantisse haben muss, die rechts vom Dezimalpunkt auf Null enden.
Jede Ganzzahl außer Null hat die folgende Form in Binärform:
1x ... x wobei die x -es die Bits rechts vom MSB darstellen (höchstwertiges Bit).
Da wir Null ausgeschlossen haben, gibt es immer ein MSB, das Eins ist - weshalb es nicht gespeichert wird. Um die ganze Zahl zu speichern, müssen wir sie in die oben genannte Form bringen: -1 Vorzeichen × 1. Mantisse × 2 Exponent - Bias .
Das heißt, Sie verschieben die Bits über den Dezimalpunkt, bis nur noch das MSB links vom MSB angezeigt wird. Alle Bits rechts vom Dezimalpunkt werden dann in der Mantisse gespeichert.
Daraus können wir ersehen, dass wir neben dem MSB höchstens 52 Binärziffern speichern können.
Daraus folgt, dass die höchste Zahl, in der alle Bits explizit gespeichert sind, ist
111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles.
Dazu müssen wir den Exponenten so einstellen, dass der Dezimalpunkt um 52 Stellen verschoben wird. Wenn wir den Exponenten um eins erhöhen, können wir die Ziffer rechts nach links nach dem Dezimalpunkt nicht kennen.
111(omitted)111x.
Konventionell ist es 0. Wenn Sie die gesamte Mantisse auf Null setzen, erhalten Sie die folgende Nummer:
100(omitted)00x. = 100(omitted)000.
Das ist eine 1, gefolgt von 53 Nullen, 52 gespeicherten und 1 aufgrund des Exponenten hinzugefügten.
Es stellt 2 53 dar , was die Grenze (sowohl negativ als auch positiv) markiert, zwischen der wir alle ganzen Zahlen genau darstellen können. Wenn wir eins zu 2 53 addieren wollten , müssten wir die implizite Null (bezeichnet mit x
) auf eins setzen, aber das ist unmöglich.
math.floor
Gibt in Version 2.6 einen Float zurück, in Version 3 jedoch eine Ganzzahl . Zu diesem Zeitpunkt (fast sechs Jahre nach dem OP) könnte dieses Problem selten auftreten.