slangswinger
slangswinger

Reputation: 47

rounding floats in python (handling 5s)

I am trying figure out the best way to robustly round floats in python using the round half up algorithm. It seems the best way to do this is using the decimal library. However I would expect this method to carry over the rounding up of a 5 across a float. For example:

from decimal import *
Decimal('3.445').quantize(Decimal('0.1'), rounding=ROUND_HALF_UP)

The result is 3.4. What I would expect the algorithm to do is carry over the round up of the 5 such that 3.445 = 3.45 = 3.5.

Does anybody know how to do this in python? I cannot seem to find a robust way of doing this.

Upvotes: 0

Views: 172

Answers (1)

blhsing
blhsing

Reputation: 106480

Rounding half up doesn't work by carrying over the round-ups from lower digits, but simply determines the half point at the given exponent. Since 3.445 % 0.1 == 0.045, which is less than half of 0.1, it would correctly round down to 3.4.

You can instead implement the desired rounding logic by rounding half up the given decimal number from the second-least significant digit to the given target exponent in a loop:

def round_half_up_carryover(d, target_exp):
    exp = Decimal(10) ** (d.as_tuple()[2] + 1)
    while exp <= target_exp:
        d = d.quantize(exp.normalize(), rounding=ROUND_HALF_UP)
        exp *= 10
    return d

so that:

print(round_half_up_carryover(Decimal('3.445'), Decimal('0.1')))

would output:

3.5

Upvotes: 1

Related Questions