Zeinab Abbasimazar
Zeinab Abbasimazar

Reputation: 10439

How to round to the nearest lower float in Python?

I have a list of floats which I want to round up to 2 numbers; I used below line for this purpose:

item = ['41618.45110', '1.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '0.00', '41619.001202', '3468.678822']
print ["{0:.2f}".format(round(float(x), 2)) if re.match("^\d+(\.\d+)?$", x) else x for x in item]

It rounds all the list members to the nearest upper float which causes 3468.678822 to be rounded to 3468.68, but I want to round them to the nearest lower float, so 3468.678822 should be rounded to 3468.67. There is an exception for 0; I want numbers equal to 0 to remain 0.

I tried using above command without round and even float function and the result was the same. I also tried:

[x[:x.index('.')] if re.match("^\d+(\.\d+)?$", x) else x for x in item]

Which gave me Substring not found error.

Upvotes: 1

Views: 854

Answers (2)

Tespy
Tespy

Reputation: 1005

I just made a couple functions for this kind of precision rounding. Added some documentation for how it works, in case you'd be curious as to how they work.

import math

def precCeil(num, place = 0):
    """
    Rounds a number up to a given place.

    num - number to round up
    place - place to round up to (see notes)
    """

    # example: 5.146, place is 1

    # move the decimal point to the right or left, depending on
    # the sign of the place
    num = num * math.pow(10, place) # 51.46

    # round it up normally
    num = math.ceil(num) #52

    # put the decimal place back where it was
    num = num * math.pow(10, -place) #5.2

    # return the result rounded, to avoid a weird glitch where
    # a bunch of trailing numbers are added to the result (see notes). 
    return round(num, place) 

""" 
Notes:
Here is how the places work:
0 - ones place
positive ints - to the right of the decimal point
negative ints - to the left of the ones place

This function works perfectly fine on Python 3.4 and 2.7, last I checked.

If you want a version of this that rounds down, just replace the calls 
to math.ceil with calls to math.floor.

Now, the glitch with the trailing numbers. Just have flexCeil return 
num instead of round(num, place). Then test it with flexCeil(12345.12345, 2). 
You get 12345.130000000001.

Interestingly enough, this glitch doesnt happen when you change the
function to round down, instead.
"""

Upvotes: 0

gallium
gallium

Reputation: 301

You can use a cast to do that :

a = '3468.678822'

def round_2(n):
    return ((int)(n*100)/100)

print(round_2(float(a)))

>>> 3468.67 

Upvotes: 1

Related Questions