Today I learned how to do ceiling division in Python just with
Follow me on Twitter, where I write about Python, APL, and maths.
I recently published a tweet telling people about the floor division operator in Python,
Are you familiar with the `//` operator in Python 🐍?— Rodrigo 🐍📝 (@mathsppblog) September 14, 2021
`//` is the “floor division” operation, which is equivalent to dividing and then rounding down.
`q = n // m` is always an integer, and the value of `q` is equivalent to `q = floor(n / m)`.
How many years fit in 10_000 days? pic.twitter.com/ecRQoz3qkM
This operator is equivalent to doing regular division and then flooring down:
>>> # How many years in 10_000 days? >>> from math import floor; floor(10_000 / 365) 27 >>> 10_000 // 365 27
Then, someone asked if Python also had a built-in for ceiling division, that is, an operator that divided the operands and then rounded up.
While there is no direct built-in operator for that, someone replied saying that we can use a couple of minus signs and floor division to do that.
Ceiling division with
b would be equivalent to
ceil(a / b).
And they showed that we can do it with
-(-a // b):
>>> from math import ceil >>> a, b = 10, 3 >>> ceil(a / b) 4 >>> -(-a // b) 4
Why does this work?
floor rounds down and
ceil rounds up.
-a in the division, it's as if you flip
a upside down,
so “its ceiling is now on the floor”, so you can use
-a // b.
Then, you just need to put everything back in place,
using a final negation:
-(-a // b).
At first, I thought this would fail for some combination of positive/negative values for
but it most certainly doesn't.
For one, the explanation works regardless of the sign of
Secondly, one can always test it:
>>> for a, b in [(10, 3), (10, -3), (-10, 3), (-10, -3)]: ... assert ceil(a / b) == -(-a // b) ... >>>
Here's the original tweet that taught me this:
You can do ceiling division with '//' and some unary '-' signs, since '//' truncates to the next *lowest* number. If the divisor is negative, that means it goes to the next "most-negative" number, which, when negated, is actually "truncating up". pic.twitter.com/uAQmJJbYhw— Paul McGuire - pyparsing guy (@ptmcguire) September 15, 2021
I hope you learned something new! If you did, consider following the footsteps of the readers who bought me a slice of pizza 🍕. Your small contribution helps me produce this content for free and without spamming you with annoying ads.