I am trying to round integers in python. I looked at the built-in round() function but it seems that that rounds floats.

My goal is to round integers to the closest multiple of 10. i.e.: 5-> 10, 4-> 0, 95->100, etc.

5 and higher should round up, 4 and lower should round down.

This is the code I have that does this:

``````def round_int(x):
last_dig = int(str(x)[-1])
if last_dig >= 5:
x += 10
return (x/10) * 10
``````

Is this the best way to achieve what I want to achieve? Is there a built-in function that does this? Additionally, if this is the best way, is there anything wrong with the code that I missed in testing?

Actually, you could still use the round function:

``````>>> print round(1123.456789, -1)
1120.0
``````

This would round to the closest multiple of 10. To 100 would be -2 as the second argument and so forth.

round() can take ints and negative numbers for places, which round to the left of the decimal. The return value is still a float, but a simple cast fixes that:

``````>>> int(round(5678,-1))
5680
>>> int(round(5678,-2))
5700
>>> int(round(5678,-3))
6000
``````

Slightly simpler:

``````def round_int(x):
return 10 * ((x + 5) // 10)
``````

## About the `round(..)` function returning a float

That float (double-precision in Python) is always a perfect representation of an integer, as long as it’s in the range [-253..253]. (Pedants pay attention: it’s not two’s complement in doubles, so the range is symmetric about zero.)

See the discussion here for details.

I wanted to do the same thing, but with 5 instead of 10, and came up with a simple function. Hope it’s useful:

``````def roundToFive(num):
remaining = num % 5
if remaining in range(0, 3):
return num - remaining
return num + (5 - remaining)
``````

if you want the algebric form and still use round for it it’s hard to get simpler than:

``````interval = 5
n = 4
print(round(n/interval))*interval
``````

This function will round either be order of magnitude (right to left) or by digits the same way that format treats floating point decimal places (left to right:

``````def intround(n, p):
''' rounds an intger. if "p"<0, p is a exponent of 10; if p>0, left to right digits '''
if p==0: return n
if p>0:
ln=len(str(n))
p=p-ln+1 if n<0 else p-ln
return (n + 5 * 10**(-p-1)) // 10**-p * 10**-p

>>> tgt=5555555
>>> d=2
>>> print('\t{} rounded to {} places:\n\t{} right to left \n\t{} left to right'.format(
tgt,d,intround(tgt,-d), intround(tgt,d)))
``````

Prints

``````5555555 rounded to 2 places:
5555600 right to left
5600000 left to right
``````

You can also use Decimal class:

``````import decimal
import sys

def ri(i, prec=6):
ic=long if sys.version_info.major<3 else int
with decimal.localcontext() as lct:
if prec>0:
lct.prec=prec
else:
lct.prec=len(str(decimal.Decimal(i)))+prec
n=ic(decimal.Decimal(i)+decimal.Decimal('0'))
return n
``````

On Python 3 you can reliably use round with negative places and get a rounded integer:

``````def intround2(n, p):
''' will fail with larger floating point numbers on Py2 and require a cast to an int '''
if p>0:
return round(n, p-len(str(n))+1)
else:
return round(n, p)
``````

On Python 2, round will fail to return a proper rounder integer on larger numbers because round always returns a float:

``````>>> round(2**34, -5)
17179900000.0                     # OK
>>> round(2**64, -5)
1.84467440737096e+19              # wrong
``````

The other 2 functions work on Python 2 and 3