Search code examples
pythonroundingfloating-accuracy

Round up floating thousandth place 5s up in Python


I'm using this function to round up floating 5s in Python:

def round_half_up_xx(n, decimals=2):
    multiplier = 10 ** decimals
    return math.floor(n*multiplier + 0.5) / multiplier

I'm getting weird results:

  • round_half_up_xx(81.225) => 81.22
  • round_half_up_xx(81.235) => 81.24

How do I revise the code so that round_half_up_xx(81.225) yields 81.23?


Solution

  • You can't, because 81.225 isn't a real value in IEEE 754 binary floating point. It's shorthand for 81.2249999999999943..., which, as it doesn't end with a 5 in the thousandths place, rounds to 81.22 without concerning itself with special rounding rules.

    If you want true accuracy of this sort, you'll need to use the decimal module, initializing the decimal.Decimal values with ints or str (if you initialize with float, it will accurately reflect the precision of the float as best it can, so it won't be 81.225 either). With decimal precision, it can do decimal rounding with whatever rounding strategy you like, without reimplementing it from scratch like you've done here.