To wcale nie jest trywialne! Właściwością reprezentacji zmiennoprzecinkowej IEEE jest to, że int∘floor = ⌊⋅⌋, jeśli wielkość danych liczb jest wystarczająco mała, ale możliwe są różne reprezentacje, gdzie int (floor (2.3)) może wynosić 1.
Ten post wyjaśnia, dlaczego działa w tym zakresie .
Podwójnie możesz bez problemu reprezentować 32-bitowe liczby całkowite. Nie może być żadnych problemów z zaokrąglaniem. Dokładniej, liczby podwójne mogą reprezentować wszystkie liczby całkowite między 2 53 a -2 53 włącznie .
Krótkie wyjaśnienie : W podwójnej pamięci można zapisać do 53 cyfr binarnych. Gdy potrzebujesz więcej, liczba jest wypełniona zerami po prawej stronie.
Wynika z tego, że 53 z nich to największa liczba, którą można przechowywać bez wypełnienia. Oczywiście wszystkie liczby (całkowite) wymagające mniejszej liczby cyfr mogą być przechowywane dokładnie.
Dodanie jednego do 111 (pominięte) 111 (53 jedynki) daje 100 ... 000, (53 zera). Jak wiemy, możemy przechowywać 53 cyfry, co sprawia, że dopełnienie zera po prawej stronie jest zerowe.
Stąd pochodzi 2 53 .
Więcej szczegółów: Musimy rozważyć, jak działa zmiennoprzecinkowy IEEE-754.
1 bit 11 / 8 52 / 23 # bits double/single precision
[ sign | exponent | mantissa ]
Liczbę oblicza się następnie w następujący sposób (z wyłączeniem szczególnych przypadków, które nie są tu istotne):
-1 znak × 1. mantysa × 2 wykładnik - błąd
gdzie odchylenie = 2 wykładnik - 1 - 1 , tj. 1023 i 127 odpowiednio dla podwójnej / pojedynczej precyzji.
Wiedząc, że pomnożenie przez 2 X po prostu przesuwa wszystkie bity X miejsc w lewo, łatwo zauważyć, że każda liczba całkowita musi mieć wszystkie bity w mantysie, które kończą się po prawej stronie przecinka dziesiętnego na zero.
Każda liczba całkowita oprócz zera ma następującą postać binarną:
1x ... x, gdzie x-y reprezentują bity po prawej stronie MSB (najbardziej znaczący bit).
Ponieważ wykluczyliśmy zero, zawsze będzie MSB, który jest jeden - dlatego nie jest przechowywany. Aby zapisać liczbę całkowitą, musimy doprowadzić ją do powyższej postaci: znak -1 × 1. mantysa × 2 wykładnik - odchylenie .
To oznacza to samo, co przesunięcie bitów ponad przecinek dziesiętny, dopóki MSB nie będzie tylko po lewej stronie MSB. Wszystkie bity po prawej stronie przecinka są następnie zapisywane w mantysie.
Z tego wynika, że oprócz MSB możemy przechowywać maksymalnie 52 cyfry binarne.
Wynika z tego, że najwyższą liczbą, w której wszystkie bity są jawnie przechowywane, jest
111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles.
W tym celu musimy ustawić wykładnik, tak aby przecinek dziesiętny został przesunięty o 52 miejsca. Gdybyśmy zwiększyli wykładnik o jeden, nie możemy znać cyfry od prawej do lewej po przecinku.
111(omitted)111x.
Zgodnie z konwencją wynosi 0. Po ustawieniu całej mantysy na zero otrzymujemy następującą liczbę:
100(omitted)00x. = 100(omitted)000.
To 1, po którym następuje 53 zera, 52 zapisane i 1 dodane ze względu na wykładnik potęgi.
Reprezentuje 2 53 , co oznacza granicę (zarówno ujemną, jak i dodatnią), pomiędzy którą możemy dokładnie przedstawić wszystkie liczby całkowite. Gdybyśmy chcieli dodać jeden do 2 53 , musielibyśmy ustawić wartość domyślną zero (oznaczoną przez x
) na jeden, ale to niemożliwe.
math.floor
zwraca liczbę zmiennoprzecinkową w v2.6 , ale zwraca liczbę całkowitą w v3 . W tym momencie (prawie sześć lat po PO) ten problem może pojawiać się rzadko.