在Python中是否有相当于//运算符的上限?

时间:2013-02-11 22:33:09

标签: python python-3.x

我发现了Python中的//运算符,它在Python 3中与底层划分。

是否有运营商与ceil分开? (我知道在Python 3中进行浮点除法的/运算符。)

9 个答案:

答案 0 :(得分:233)

你可以做颠倒的地板部门:

def ceildiv(a, b):
    return -(-a // b)

这是因为Python's division operator does floor division(与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]

答案 1 :(得分:50)

没有运营商与ceil分开。您需要import math并使用math.ceil

答案 2 :(得分:17)

(x + (d-1)) // d除以x,即d时,您可以(x + 4) // 5

答案 3 :(得分:14)

你也可以随便进行内联

((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

答案 4 :(得分:8)

请注意,math.ceil的精度限制为53位。如果您正在使用大整数,则可能无法获得准确的结果。

gmpy2图书馆提供c_div功能,使用天花板舍入。

免责声明:我维持gmpy2。

答案 5 :(得分:5)

解决方案1:通过求反将地板转换为天花板

def ceiling_division(n, d):
    return -(n // -d)

这让人想起Penn & Teller levitation trick,“将世界颠倒(带负号),使用普通地板分割(交换了天花板和地板),然后使世界朝上(带再次求反)”

解决方案2:让divmod()完成工作

def ceiling_division(n, d):
    q, r = divmod(n, d)
    return q + bool(r)

divmod()函数为整数提供(a // b, a % b)(由于舍入误差,这对于浮点数可能不太可靠)。每当存在非零余数时,带有bool(r)的步骤都会向商数加1。

解决方案3:除法前调整分子

def ceiling_division(n, d):
    return (n + d - 1) // d

向上平移分子,以便将楼层划分向下舍入到所需的上限。请注意,这仅适用于整数。

解决方案4:转换为浮点数以使用math.ceil()

def ceiling_division(n, d):
    return math.ceil(n / d)

math.ceil()代码很容易理解,但是它从int转换为float并返回。这不是很快,并且可能存在舍入问题。此外,它还依赖于Python 3语义,其中“真除法”产生一个浮点数,而 ceil()函数返回一个整数。

答案 6 :(得分:0)

如果您想将一个号码的单元格设置为多个。它的工作原理就像我们在 excel 中有 Math.celling 一样。

def excel_celling(number=None, multiple_off=None):
    quotient = number // multiple_off
    reminder = number % multiple_off
    celling_value = quotient * multiple_off + (multiple_off, 0)[reminder==0]
    return int(celling_value)


assert excel_celling(99.99, 100) == 100, "True"
print(excel_celling(99.99, 100) , 100)
assert excel_celling(1, 100) == 100, "True"
print(excel_celling(1, 100),100)
assert excel_celling(99, 100) == 100, "True"
print(excel_celling(99, 100),100)
assert excel_celling(90, 100) == 100, "True"
print(excel_celling(90, 100),100)
assert excel_celling(101, 100) == 200, "True"
print(excel_celling(101, 100),200)
assert excel_celling(199, 100) == 200, "True"
print(excel_celling(199, 100),200)
assert excel_celling(199.99, 100) == 200, "True"
print(excel_celling(199.99, 100),200)
assert excel_celling(200, 100) == 200, "True"
print(excel_celling(200, 100),200)

结果

100 100

100 100

100 100

100 100

200 200

200 200

200 200

200 200

答案 7 :(得分:-1)

我之所以来到这里是因为二进制模块化组,并且想与列表的共享中间部分进行交互。例如,[1,2,3,4]具有23

要与列表的中央进行交互并使用上限运算符:

foo    = [1,2,3,4]
length = len(foo)
floor  = (len(foo)//2)
ceil   = floor+1
floor == 2 #True
ceil  == 3 #True

答案 8 :(得分:-7)

简单的解决方案: a // b + 1