Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Round with integer division

Tags:

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:

skip = int(round(1.0 * total / surplus)) 

==============

@John: Floating point is not reproducible across platforms. If you want your code to pass tests across different platforms then you need to avoid floating point (or add some hacky espilon stuff to your tests and hope it works). The above may be simple enough that it would be the same on most/all platforms, but I'd rather not make that determination as it is easier to avoid floating point altogether. How is that "not in the spirit of Python"?

like image 562
gaefan Avatar asked Oct 16 '10 19:10

gaefan


People also ask

Does integer division round down or up?

Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.

Does integer division round up in Java?

When dividing two integers, Java uses integer division. In integer division, the result is also an integer. The result is truncated (the fractional part is thrown away) and not rounded to the closest integer.

Does integer division round down in C++?

When doing an integer division in c++, the result will always be rounded down, so your rounding system isn't off :) For example even if you divide 1999 by 1000, the result will be 1 if both 1999 and 1000 are integers.

Does Python round up integer division?

Use Floor Division Operator to Round Up a Number in Python It works in the same way as a simple division operator, / , but it also rounds the number down.


2 Answers

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.

like image 86
John Machin Avatar answered Oct 29 '22 00:10

John Machin


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).

like image 25
Amber Avatar answered Oct 28 '22 23:10

Amber