Is there is a simple, pythonic way of rounding to the nearest whole number without using floating point? I\'d like to do the following but with integer arithmetic:
This should work too:
def rint(n):
return (int(n+.5) if n > 0 else int(n-.5))
Yet another funny way:
q, r = divmod(total, surplus)
skip = q + int(bool(r))
skip = (((total << 1) // surplus) + 1) >> 1
Shifting things left by one bit effectively multiplies by two, shifting things right by one bit divides by two rounding down. Adding one in the middle makes it so that "rounding down" is actually rounding up if the result would have been above a .5 decimal part.
It's basically the same as if you wrote...
skip = int((1.0*total/surplus) + 0.5)
except with everything multplied by 2, and then later divided by 2, which is something you can do with integer arithmetic (since bit shifts don't require floating point).
Simply take care of the rounding rule before you ever divide. For the simplest round-half-up:
if total % surplus < surplus / 2:
return total / surplus
else:
return (total / surplus) + 1
Tweak a little bit if you need to do a proper round-to-even.
Inspired by zhmyh's answer answer, which is
q, r = divmod(total, surplus)
skip = q + int(bool(r)) # rounds to next greater integer (always ceiling)
, I came up with the following solution:
q, r = divmod(total, surplus)
skip = q + int(2 * r >= surplus) # rounds to nearest integer (floor or ceiling)
Since the OP asked for rounding to the nearest whole number, zhmhs's solution is in fact slightly incorrect, because it always rounds to the next greater whole number, while my solution works as demanded.
(If you feel that my answer should better have been an edit or comment on zhmh's answer, let me point out that my suggested edit for it was rejected, because it should better have been a comment, but I do not have enough reputation yet for commenting!)
In case you wonder how divmod
is defined: According to its documentation
For integers, the result is the same as
(a // b, a % b)
.
We therefore stick with integer arithmetic, as demanded by the OP.
You can do this quite simply:
(n + d // 2) // d
, where n
is the dividend and d
is the divisor.
Alternatives like (((n << 1) // d) + 1) >> 1
or the equivalent (((n * 2) // d) + 1) // 2
may be SLOWER in recent CPythons, where an int
is implemented like the old long
.
The simple method does 3 variable accesses, 1 constant load, and 3 integer operations. The complicated methods do 2 variable accesses, 3 constant loads, and 4 integer operations. Integer operations are likely to take time which depends on the sizes of the numbers involved. Variable accesses of function locals don't involve "lookups".
If you are really desparate for speed, do benchmarks. Otherwise, KISS.