Round integers to the nearest 10

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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

Method 3

Slightly simpler:

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

Method 4

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.

Method 5

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)

Method 6

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

Method 7

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:nt{} right to left nt{} 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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x