Я узнал об операторе //
в Python, который в Python 3 делает разделение с полом.
Есть ли оператор, который вместо этого делится на ceil? (Я знаю об операторе /
, который в Python 3 выполняет разделение с плавающей запятой.)
Я узнал об операторе //
в Python, который в Python 3 делает разделение с полом.
Есть ли оператор, который вместо этого делится на ceil? (Я знаю об операторе /
, который в Python 3 выполняет разделение с плавающей запятой.)
Нет оператора, который делит на ceil. Вам нужно import math
и использовать math.ceil
Вы можете просто выполнить перевернутое разделение полов:
def ceildiv(a, b):
return -(-a // b)
Это работает, потому что Оператор разделения Python выполняет деление пола (в отличие от C, где целочисленное деление усекает дробную часть).
Это также работает с большими целыми числами Python, потому что нет (с потерями) преобразования с плавающей запятой.
Здесь демонстрация:
>>> from __future__ import division # a/b is float division
>>> from math import ceil
>>> b = 3
>>> for a in range(-7, 8):
... print(["%d/%d" % (a, b), int(ceil(a / b)), -(-a // b)])
...
['-7/3', -2, -2]
['-6/3', -2, -2]
['-5/3', -1, -1]
['-4/3', -1, -1]
['-3/3', -1, -1]
['-2/3', 0, 0]
['-1/3', 0, 0]
['0/3', 0, 0]
['1/3', 1, 1]
['2/3', 1, 1]
['3/3', 1, 1]
['4/3', 2, 2]
['5/3', 2, 2]
['6/3', 2, 2]
['7/3', 3, 3]
Вы можете сделать (x + (d-1)) // d
при делении x
на d
, т.е. (x + 4) // 5
.
Вы всегда можете просто сделать это inline, а
((foo - 1) // bar) + 1
В python3 это просто застенчиво на порядок быстрее, чем форматирование поплавка и вызов ceil(), если вы заботитесь о скорости. Который вы не должны, если только вы не доказали, что вам это нужно.
>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647
Обратите внимание, что значение math.ceil ограничено 53 битами точности. Если вы работаете с большими целыми числами, вы не можете получить точные результаты.
gmpy2 libary предоставляет функцию c_div
, которая использует потолочное округление.
Отказ от ответственности: я поддерживаю gmpy2.
def ceiling_division(n, d):
return -(n // -d)
Напоминающий трюк с левитацией Пенна и Теллера, он "переворачивает мир вверх ногами (с отрицанием), использует разделение на ровные полы (где поменялись местами потолок и пол), а затем переворачивает мир вправо вверх (снова с отрицанием) "
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
Функция divmod() дает (a//b, a % b)
для целых чисел (это может быть менее надежно с плавающей точкой из-за ошибки округления). Шаг с bool(r)
добавляет единицу к частному всякий раз, когда есть ненулевой остаток.
def ceiling_division(n, d):
return (n + d - 1) // d
Переведите числитель вверх, чтобы деление пола округлилось до предполагаемого потолка. Обратите внимание, это работает только для целых чисел.
def ceiling_division(n, d):
return math.ceil(n / d)
Код math.ceil() легко понять, но он конвертирует из целых чисел в плавающие и обратно. Это не очень быстро и может иметь проблемы с округлением. Кроме того, он опирается на семантику Python 3, где "истинное деление" создает число с плавающей точкой, а функция ceil() возвращает целое число.
Я пришел сюда из-за бинарных модульных групп и хотел взаимодействовать с обоими общими серединами списка. Например, [1,2,3,4]
имеет 2
и 3
.
Для взаимодействия с серединой списка и использования оператора потолка:
foo = [1,2,3,4]
length = len(foo)
floor = (len(foo)//2)
ceil = floor+1
floor == 2 #True
ceil == 3 #True