Python 3 and rounding

Back to Programming Languages forum

Bernd Bausch     2019-07-05 03:40:56

Many Codeabbey tasks rely on correct rounding. I suppose that almost everybody learned at school that xxx.5 fractions are always rounded up. Unfortunately, Python 3 does it differently: xxx.5 fractions are rounded to the next even number.

If I understand it right, the rationale for this behaviour is to make rounding up and rounding down equally likely. The "school method" has the effect that, overall, rounding up is ever so slightly more likely than rounding down.

Unfortunately, Codeabbey expects the "school method". This means that I can't use the round() function in Python 3. One solution is to use Python's decimal module, another is to write my own rounding function:

import math
def abbeyround(x):
    if (x-math.floor(x) == 0.5):
        return int(x)+1
    else:
        return int(round(x))

It's a naive approach; I am sure it can be improved.

Arman Cam     2019-07-05 07:20:41
User avatar

When the problem says round answer to an integer, I use just round() and it works well for me. I never needed to use such functions in codeabbey problems.

If you want to round spesifically upward you can use math.ceil() method.

>>> math.ceil(4.0001)
5
>>> math.ceil(4.5)
5
>>> math.ceil(4.9)
5
>>>

I am not sure its naive but you can try to do like this

def round(num):
    return round(num + 0.0001)

try to run this for see the code in action

def round_num(num):
    return round(num + 0.0001)

data = [i / 10 for i in range(10, 20)]
print({num : round_num(num) for num in data})

the only catch is that the value that you are adding to num, (0.0001 in this case) depends on the # of digits after the decimal point. if you are trying to round(1.42) for instance the value that you are adding to num must be greater than (0.01).

Edit: To ensure that you can try to add 10**(-9) to num.

Rodion (admin)     2019-07-05 13:38:41
User avatar

Wow, that is a surprise to me - but it's really so :o

>>> round(1.5)
2
>>> round(2.5)
2
>>> round(3.5)
4
>>> round(4.5)
4

Meanwhile the codeabbey "checkers" are usually following school rounding rules. Though in most task the chance hitting at precise *.5 boundary is small so I suspect many people even won't notice this.

So thanks for these news :)

It's a naive approach; I am sure it can be improved.

I think it's ok approach :) Popular formula is floor(x + 0.5), I think. Though right now I've found that checker for "Rounding" problem does follows PHP rounding rules and has a small flaw - negative values ending with .5 are rounded down. Probably I'd better fix this to be consistent with the statement...

Please login and solve 5 problems to be able to post at forum