Питон округлить целое число до СТО



Кажется, что уже должны были спросить сотни (каламбур весело =) раз, но я могу найти только функцию для округления поплавков. Как округлить целое число, например: 130 -> 200 ?

802   8  

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

попробуйте это:

int(round(130 + 49, -2))

это поздний ответ, но есть простое решение, которое сочетает в себе лучшие аспекты существующие ответы: кратное 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

    Ничего не найдено.