Dowiedziałem się o //
operatorze w Pythonie, który w Pythonie 3 dzieli się na podłogę.
Czy istnieje operator, który zamiast tego dzieli się na ceil? (Wiem o /
operatorze, który w Pythonie 3 wykonuje dzielenie zmiennoprzecinkowe).
python
python-3.x
Cradam
źródło
źródło
Odpowiedzi:
Nie ma operatora, który dzieli górą. Musisz
import math
i używaćmath.ceil
źródło
Możesz po prostu wykonać podział piętra do góry nogami:
Działa to, ponieważ operator dzielenia w Pythonie wykonuje dzielenie na podłogę (w przeciwieństwie do C, gdzie dzielenie całkowite obcina część ułamkową).
Działa to również z dużymi liczbami całkowitymi Pythona, ponieważ nie ma (stratnej) konwersji zmiennoprzecinkowej.
Oto demonstracja:
źródło
int
nie (no cóż, żadnych znaczących; w 64-bitowym Pythonie jesteś ograniczony do30 * (2**63 - 1)
liczb bitowych), a nawet tymczasowa konwersja nafloat
może utracić informacje. Porównajmath.ceil((1 << 128) / 10)
z-(-(1 << 128) // 10)
.Można to zrobić
(x + (d-1)) // d
dzielącx
przezd
, tj(x + 4) // 5
.źródło
math.ceil()
.sys.float_info.max
i nie wymaga importu.Rozwiązanie 1: Zamień podłogę na sufit z negacją
Przypomina sztuczkę lewitacji Penn & Teller , która „odwraca świat do góry nogami (z negacją), wykorzystuje zwykły podział podłogi (gdzie zamieniono sufit i podłogę), a następnie obraca świat w prawą stronę (ponownie z negacją) "
Rozwiązanie 2: Pozwól divmod () wykonać pracę
Funkcja divmod () podaje
(a // b, a % b)
liczby całkowite (może to być mniej niezawodne w przypadku wartości zmiennoprzecinkowych z powodu błędu zaokrąglenia). Krok zbool(r)
dodaje jedynkę do ilorazu za każdym razem, gdy pozostaje niezerowa reszta.Rozwiązanie 3: Dostosuj licznik przed dzieleniem
Przesuń licznik w górę, aby podział podłogi został zaokrąglony w dół do przewidywanego sufitu. Uwaga, działa to tylko dla liczb całkowitych.
Rozwiązanie 4: Konwertuj na elementy zmiennoprzecinkowe, aby używać funkcji math.ceil ()
Kod math.ceil () jest łatwy do zrozumienia, ale konwertuje z liczb całkowitych na zmiennoprzecinkowe iz powrotem. Nie jest to zbyt szybkie i może powodować problemy z zaokrąglaniem. Opiera się również na semantyce Pythona 3, gdzie „prawdziwy podział” tworzy liczbę zmiennoprzecinkową, a funkcja ceil () zwraca liczbę całkowitą.
źródło
-(-a // b)
o_O-(a // -b)
jest szybszy niż-(-a // b)
, przynajmniej jeśli chodzi o synchronizację przykładów zabawek zpython -m timeit ...
Zawsze możesz to również zrobić w trybie inline
W pythonie3 jest to o rząd wielkości szybsze niż wymuszanie dzielenia typu float i wywoływanie ceil (), pod warunkiem, że zależy Ci na szybkości. Czego nie powinieneś, chyba że udowodniłeś poprzez użycie, że musisz.
źródło
number=100000000
). W przypadku pojedynczego połączenia różnica jest niewielka.foo = -8
ibar = -4
, na przykład, odpowiedź powinna wynosić 2, a nie 3, tak jak-8 // -4
. Podział podłogi w Pythonie jest definiowany jako „podział matematyczny z funkcją„ podłogi ”zastosowaną do wyniku”, a podział sufitu jest tym samym, ale zceil()
zamiastfloor()
.Zauważ, że math.ceil jest ograniczona do 53 bitów precyzji. Jeśli pracujesz z dużymi liczbami całkowitymi, możesz nie uzyskać dokładnych wyników.
Gmpy2 Libary zapewnia
c_div
funkcję zaokrąglania, który wykorzystuje na suficie.Zastrzeżenie: utrzymuję gmpy2.
źródło
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(jak również zastępowaniepython3
)True
Proste rozwiązanie: a // b + 1
źródło