8 ответов:
округление обычно выполняется на числах с плавающей запятой, и здесь есть три основные функции, которые вы должны знать:
round(округление до ближайшего целого числа),math.floor(всегда округляет вниз), иmath.ceil(всегда округляет).вы спрашиваете о целых и округление до сотен, но мы все еще можем использовать
math.ceilдо тех пор, как ваши номера меньше, чем 253. Использоватьmath.ceil, мы просто делим на 100 первый раунд вверх, а затем умножить на 100:>>> import math >>> def roundup(x): ... return int(math.ceil(x / 100.0)) * 100 ... >>> roundup(100) 100 >>> roundup(101) 200деление на 100 сначала и умножение на 100 после этого "сдвигает" два десятичных знака вправо и влево, так что
math.ceilработает на сотни. Вы могли бы использовать10**nвместо 100, если вы хотите округлить до десятков (n = 1), тысячи (n = 3) и т. д.альтернативный способ сделать это-избежать чисел с плавающей запятой (они имеют ограниченную точность) и вместо этого использовать только целые числа. Целые числа имеют произвольное значение точность в Python, так что это позволяет округлять числа любого размера. Правило округления простое: найдите остаток после деления на 100 и добавьте 100 минус этот остаток, если он не равен нулю:
>>> def roundup(x): ... return x if x % 100 == 0 else x + 100 - x % 100это работает для чисел любого размера:
>>> roundup(100) 100 >>> roundup(130) 200 >>> roundup(1234567891234567891) 1234567891234567900Lя сделал мини-тест из двух решений:
$ 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чистое целочисленное решение быстрее в два раза по сравнению с
math.ceilрешение.Томас предложил целое число основанное решение, которое идентично тому, которое я имею выше, за исключением того, что оно использует трюк путем умножения булевых значений. Интересно видеть, что нет никакого преимущества в скорости написания кода таким образом:
$ python -m timeit -s 'x = 130' 'x + 100*(x%100>0) - x%100' 10000000 loops, best of 3: 0.167 usec per loopв качестве заключительного замечания позвольте мне также отметить, что если бы вы хотели округлить 101-149 до 100 и округлить 150-199 до 200, например, округлить до ближайший сто, то встроенный
вот общий способ округления до ближайшего кратного любого положительного целого числа:
def roundUpToMultiple(number, multiple): num = number + (multiple - 1) return num - (num % multiple)пример использования:
>>> roundUpToMultiple(101, 100) 200 >>> roundUpToMultiple(654, 321) 963
это поздний ответ, но есть простое решение, которое сочетает в себе лучшие аспекты существующие ответы: кратное
100Сx- этоx - x % -100(или если вы предпочитаете,x + (-x) % 100).>>> x = 130 >>> x -= x % -100 # Round x up to next multiple of 100. >>> x 200это быстро и просто, дает правильные результаты для любого целого числа
x(как ответ Джона Мэчина), а также дает разумные результаты (по модулю обычных предостережений о представлении с плавающей запятой), еслиxэто поплавок (как у Мартина Гейслера ответ.)>>> x = 0.1 >>> x -= x % -100 >>> x 100.0
на
aнеотрицательным,bположительный, оба целых числа:>>> 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)]обновлениепринятый в настоящее время ответ разваливается С целыми числами, которые float (x) / float(y) не могут быть точно представлены как
float. Смотрите этот код: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__выход:
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и вот некоторые тайминги:
>\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
Если ваш int-x:
x + 100 - x % 100однако, как указано в комментариях, это вернет 200, если
x==100.Если это не ожидаемое поведение, вы можете использовать
x + 100*(x%100>0) - x%100
предупреждение: преждевременная оптимизация впереди...
поскольку так много ответов здесь делают время этого, я хотел бы добавить еще одну альтернативу.
принимая @Martin Geisler ' s
def roundup(x): return x if x % 100 == 0 else x + 100 - x % 100(что мне нравится больше всего по нескольким причинам)
но факторинг % action
def roundup2(x): x100= x % 100 return x if x100 == 0 else x + 100 - x100дает ~ 20% улучшение скорости по сравнению с оригиналом
def roundup3(x): x100 = x % 100 return x if not x100 else x + 100 - x100еще лучше и ~36% быстрее оригинал
наконец-то я подумал, что могу бросить
notоператор и изменить порядок ветвей в надежде, что это также увеличит скорость, но был озадачен, чтобы узнать, что это на самом деле медленнее падение обратно, чтобы быть только 23% быстрее, чем оригинал.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объяснения о том, почему 3 быстрее, чем 4 было бы наиболее приветствуется.
попробуйте это:
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пример использования:
>>> ceilm(257,5) 260 >>> ceilm(260,5) 260
Comments