Wygląda na to, że powinno się już zadać setki razy (kalambur jest zabawą =) razy, ale mogę znaleźć tylko funkcję zaokrąglania spławików. Jak zaokrąglić w górę liczbę całkowitą, na przykład: 130 -> 200
?Python zaokrągla liczbę całkowitą do następnej setki
Odpowiedz
Zaokrąglanie jest zazwyczaj wykonywane na liczbach zmiennoprzecinkowych, a tu są trzy podstawowe funkcje, które trzeba wiedzieć: round
(zaokrągla do najbliższej liczby całkowitej), math.floor
(zawsze zaokrągla w dół) i math.ceil
(zawsze zaokrągla w górę).
Pytasz o liczby całkowite i zaokrąglając do setek, ale nadal możemy używać wartości math.ceil
, o ile Twoje liczby są mniejsze niż 2 . Aby korzystać math.ceil
, po prostu podzielić przez 100, po pierwsze, zaokrąglić w górę, i rozmnażajcie się z 100 potem:
>>> import math
>>> def roundup(x):
... return int(math.ceil(x/100.0)) * 100
...
>>> roundup(100)
100
>>> roundup(101)
200
dzieląc przez 100 pierwszego i pomnożyć 100 później „przesuwa” dwa miejsca po przecinku na prawo i lewo, tak że math.ceil
działa na setkach. Można użyć 10**n
zamiast 100 jeśli chcesz zaokrąglić do kilkudziesięciu (n = 1
), tysiące (n = 3
) itp
Alternatywnym sposobem, aby to zrobić, aby uniknąć liczb zmiennoprzecinkowych (mają ograniczone precyzja) i zamiast używać tylko liczby całkowite. Liczby całkowite mają dowolną precyzję w Pythonie, więc pozwala to na zaokrąglanie liczb o dowolnym rozmiarze. Reguła dla zaokrąglenia jest prosta: znaleźć pozostałą po podziale z 100, i dodać 100 minus to reszta, jeśli jest różna od zera:
>>> def roundup(x):
... return x if x % 100 == 0 else x + 100 - x % 100
To działa na liczbach dowolnej wielkości:
>>> roundup(100)
100
>>> roundup(130)
200
>>> roundup(1234567891234567891)
1234567891234567900L
I nie mini odniesienia dwóch roztworów:
$ python -m timeit -s 'import math' -s 'x = 130' 'int(math.ceil(x/100.0)) * 100'
1000000 loops, best of 3: 0.364 usec per loop
$ python -m timeit -s 'x = 130' 'x if x % 100 == 0 else x + 100 - x % 100'
10000000 loops, best of 3: 0.162 usec per loop
czysty roztwór całkowita jest szybciej przez współczynnik dwa w stosunku do roztworu math.ceil
.
Thomas zaproponował rozwiązanie oparte na liczbach całkowitych, które jest identyczne z tym, które mam powyżej, z tym wyjątkiem, że używa sztuczki przez pomnożenie wartości logicznych. Interesujące jest to, aby zobaczyć, że nie jest zaletą pisania kodu w ten sposób prędkość:
$ python -m timeit -s 'x = 130' 'x + 100*(x%100>0) - x%100'
10000000 loops, best of 3: 0.167 usec per loop
Jako ostatnia uwaga, pozwól mi również pamiętać, że jeśli chciał zaokrąglić 101-149 do 100 i okrągłym 150 -199 do 200, npOkrągłe do najbliższy stu, potem wbudowanej round
funkcji może zrobić dla Ciebie:
>>> int(round(130, -2))
100
>>> int(round(170, -2))
200
Nie robię tutaj normalnego zaokrąglenia, gdybym był tak, użyłbym round() – ofko
@ofko: prawda, chcesz zaokrąglić w górę. "Math.ceil" jest kanonicznym sposobem na zrobienie tego - dzielenie i pomnażanie przez 100 jest kanonicznym sposobem na wykonanie "okrągłych", "ceilowych" i "podłogowych" na setkach. –
Po ostatnich edycjach warto zaakceptować tę odpowiedź. – ofko
Spróbuj tego:
int(round(130 + 49, -2))
Jeśli int x: x + 100 - x % 100
Jednakże, jak zauważył w komentarzach, to powróci 200 jeśli x==100
.
Jeśli nie jest to oczekiwane zachowanie, można użyć x + 100*(x%100>0) - x%100
Co jeśli 'x' jest już wielokrotnością 100? –
Możesz jednak użyć innych rozwiązań, jeśli nie lubisz magicznych liczb. Jeśli zależy Ci na wydajności, działa to jednak szybciej. –
@LukeWoodward Świetny punkt, będę edytować –
Oto ogólny sposób zaokrąglania w górę do najbliższej wielokrotności każdej liczby całkowitej dodatniej:
def roundUpToMultiple(number, multiple):
num = number + (multiple - 1)
return num - (num % multiple)
wykorzystanie
próbki:
>>> roundUpToMultiple(101, 100) 200 >>> roundUpToMultiple(654, 321) 963
zbyt skomplikowana –
odpowiednik, krótsza metoda: 'liczba lambda, wielokrotność: wielokrotność * (1 + (liczba - 1) // wielokrotność)' –
Na a
nieujemnej, b
położenie, tive, obie liczby całkowite:
>>> rup = lambda a, b: (a + b - 1) // b * b
>>> [(x, rup(x, 100)) for x in (199, 200, 201)]
[(199, 200), (200, 200), (201, 300)]
AktualizacjaObecnie akceptowana odpowiedź rozpada całkowitymi tak, że pływak (x)/pływak (Y) nie może być dokładnie przedstawiony jako float
. Zobacz ten kod:
import math
def geisler(x, y): return int(math.ceil(x/float(y))) * y
def orozco(x, y): return x + y * (x % y > 0) - x % y
def machin(x, y): return (x + y - 1) // y * y
for m, n in (
(123456789123456789, 100),
(1234567891234567891, 100),
(12345678912345678912, 100),
):
print; print m, "m"; print n, "n"
for func in (geissler, orozco, machin):
print func(m, n), func.__name__
wyjścia:
123456789123456789 m
100 n
123456789123456800 geisler
123456789123456800 orozco
123456789123456800 machin
1234567891234567891 m
100 n
1234567891234568000 geisler <<<=== wrong
1234567891234567900 orozco
1234567891234567900 machin
12345678912345678912 m
100 n
12345678912345680000 geisler <<<=== wrong
12345678912345679000 orozco
12345678912345679000 machin
A oto kilka taktowania:
>\python27\python -m timeit -s "import math;x =130" "int(math.ceil(x/100.0))*100"
1000000 loops, best of 3: 0.342 usec per loop
>\python27\python -m timeit -s "x = 130" "x + 100 * (x % 100 > 0) - x % 100"
10000000 loops, best of 3: 0.151 usec per loop
>\python27\python -m timeit -s "x = 100" "(x + 99) // 100 * 100"
10000000 loops, best of 3: 0.0903 usec per loop
'Wiem, że OP dotyczył zaokrąglania liczby całkowitej' - ale chciałem zwrócić uwagę, że spróbowałbyś użyć tych 3 opcji na (0,5,10), które spodziewałbym się zwrócić 10, wtedy pierwsze dwie metody (geisler i orozco) zwracają 10 zgodnie z oczekiwaniami, podczas gdy machin zwraca 0 – epeleg
Jest to późna odpowiedź, ale nie jest to proste rozwiązanie, które łączy w sobie najlepsze aspekty istniejące odpowiedzi: następna wielokrotność 100
od x
to x - x % -100
(lub jeśli wolisz, x + (-x) % 100
).
>>> x = 130
>>> x -= x % -100 # Round x up to next multiple of 100.
>>> x
200
Jest to szybka i prosta, daje poprawne wyniki dla dowolnej liczby całkowitej x
(jak odpowiedź John Machin) i również daje rozsądne-owski wyniki (modulo zwykłe ostrzeżenia odnośnie reprezentacji zmiennoprzecinkowej) jeżeli x
to float (jak odpowiedź Martina Geislera).
>>> x = 0.1
>>> x -= x % -100
>>> x
100.0
twoje rozwiązanie jest tak szybkie jak w przypadku Martina, ale notacja jest krótszy. dzięki. % timeit 'x = 110' 'x - = x% -100' # 100000000 pętli, najlepiej od 3: 9,37 ns na pętlę VS % timeit 'x = 110' 'x + 100 * (x% 100> 0) - x% 100 ' # 100000000 pętli, najlepiej 3: 9,38 ns na pętlę – tagoma
Spróbuj to: wykorzystanie
import math
def ceilm(number,multiple):
'''Returns a float rounded up by a factor of the multiple specified'''
return math.ceil(float(number)/multiple)*multiple
próbki:
>>> ceilm(257,5)
260
>>> ceilm(260,5)
260
Warning: Wcześniaki optymalizacje przodzie ...
Ponieważ tak wiele odpowiedzi tutaj zrobić terminy to chciałem dodać kolejną alternatywę.
Biorąc @Martin Geisler jest
def roundup(x):
return x if x % 100 == 0 else x + 100 - x % 100
(które najlepiej jak kilku powodów)
ale na czynniki na działanie%
def roundup2(x):
x100= x % 100
return x if x100 == 0 else x + 100 - x100
daje poprawę szybkości około 20% w stosunku do oryginału:
def roundup3(x):
x100 = x % 100
return x if not x100 else x + 100 - x100
Jest jeszcze lepszy i jest ~ 36% szybszy niż oryginalny
w końcu pomyślałem, że mogę zrzucić operatora not
i zmienić kolejność oddziałów mając nadzieję, że to również zwiększy prędkość, ale był zaskoczony, aby dowiedzieć się, że w rzeczywistości powraca wolniej niż o 23% szybciej niż oryginał.
def roundup4(x):
x100 = x % 100
return x + 100 - x100 if x100 else x
>python -m timeit -s "x = 130" "x if x % 100 == 0 else x + 100 - x % 100"
1000000 loops, best of 3: 0.359 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if x100 == 0 else x + 100 - x100"
1000000 loops, best of 3: 0.287 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if not x100 else x + 100 - x100"
1000000 loops, best of 3: 0.23 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x + 100 - x100 if x100 else x"
1000000 loops, best of 3: 0.277 usec per loop
wyjaśnienie, dlaczego 3 jest szybsze niż 4, byłoby bardzo mile widziane.
Czy chcesz również zaokrąglić 100 do 200? – DSM
Nie, odpowiedź Thomasa robi dokładnie to, czego potrzebuję. – ofko
Odpowiedź Thomasa brzmi: od 100 do 200. Dlatego zapytałem. – DSM