1

As you may know, if you do:

>>> 11/2
# 5

And

>>> 11/2.0
# 5.5

I'd like to get 6 in this case. I tried with:

>>> 11//2
# 5

And

>>> 11//2.0
# 5.0

The last one gives the prev integer. I'd like to get the next integer. Even is the result is like x.1 I'd like to get (x+1).

How can I do this?

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Gocht
  • 9,924
  • 3
  • 42
  • 81
  • @user2357112 - Why did you reopen this? It's a clear duplicate. – TigerhawkT3 Dec 10 '15 at 23:30
  • 2
    @TigerhawkT3: That question is about rounding numbers that are already floating-point, but introducing floating-point numbers at all for a purely-integer operation like this may not be a good idea. – user2357112 Dec 10 '15 at 23:32
  • 1
    It's obvious that a floating-point number will be introduced automatically when necessary. Any floating-point number of `n.0` is equal to the integer `n`. The answers on that question are perfectly applicable. – TigerhawkT3 Dec 10 '15 at 23:35
  • @TigerhawkT3 I think that an _applicable answer_ does not mean _the same question_ – Gocht Dec 10 '15 at 23:36
  • @TigerhawkT3: `555555555555555555.0 != 555555555555555555`. Using floating-point for this just seems like asking for subtle rounding bugs down the line. – user2357112 Dec 10 '15 at 23:38
  • 1
    And "why does function foo not run unless I call it" isn't the same question as "why does function main not run unless I call it" isn't the same question, but it is the same answer. – TigerhawkT3 Dec 10 '15 at 23:38
  • Does this answer your question? [Is there a ceiling equivalent of // operator in Python?](https://stackoverflow.com/questions/14822184/is-there-a-ceiling-equivalent-of-operator-in-python) – endolith May 19 '20 at 03:19

3 Answers3

3

Generally more efficient than doing both modulus and division work, it's easy to convert floor division:

x // y

into ceil division (and unlike using math.ceil, it runs no risk of getting incorrect results due to floating point imprecision for large values):

(x + y - 1) // y

If x is exactly divisible by y, then adding y - 1 changes nothing; the floor division makes the end result unchanged. If it's not evenly divisible, this increases it above the next multiple, getting you ceil division with only a single division operation instead of two (division is expensive; doing it twice is doubly expensive), and no floating point precision issues.

The above doesn't work for negative y, but there is a solution that does work for it (at the expense of appearing more magical):

-(-x // y)

By flipping the sign on x first, you change the rounding behavior to work in the opposite direction after flipping the sign again at the end. So for x == 5 and y == -2, this second solution produces -2 (the ceiling of -2.5) correctly. It's typically more efficient than the original solution, but it's not as obvious how it works, so I can't strictly recommend it over the clearer solution when the divisor is known to be positive.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • 1
    This almost works, but it does the wrong thing when `y` is negative. For example, when `x` is 5 and `y` is -2, `(x + y - 1) // y` is -1, but the correct ceiling division result would have been -2. – user2357112 May 19 '20 at 03:39
  • @user2357112: Missed your comment back then, but I've added a solution that always works regardless of whether `y` is positive or negative (it's actually a more efficient solution, it's just a little magical looking). – ShadowRanger Nov 09 '22 at 07:41
2
rounded_up = x // y + bool(x % y)

We add 1 if the division produces a nonzero remainder. This has the benefit of not introducing floating-point imprecision, so it'll be correct in extreme cases where math.ceil produces the wrong answer.


We can also perform the operation with floor division and two negations:

rounded_up = -(-x // y)

The floor of -x/y is the negative of the ceiling of x/y, so negating again produces the ceiling of x/y. Again, we avoid floating-point rounding error by performing all operations in integer arithmetic.

user2357112
  • 260,549
  • 28
  • 431
  • 505
1

Use math.ceil

>>> import math
>>> math.ceil(11/2.0)
6.0
>>>
letsc
  • 2,515
  • 5
  • 35
  • 54