Omega Goggles
Omega Goggles

Reputation: 123

How to use traditional rounding for decimal numbers in Python (version 3)?

I'm trying to figure out how to round decimal numbers using the traditional method that is taught in elementary and middle schools using Python version 3 (specifically version 3.4.0).

For example, using the decimal number 0.745, I am trying to round it to the nearest hundredth. Traditionally, the rounded value would be 0.75, but the following code gives me 0.74:

>>> import decimal
>>> a = decimal.Decimal("0.745")
>>> round(a, 2)
Decimal('0.74')

However, changing the original value to 0.746 seems to return 0.75:

>>> import decimal
>>> b = decimal.Decimal("0.746")
>>> round(b, 2)
Decimal('0.75')

This seems to contradict traditional rounding (if I remember correctly). Can someone lead me to the correct way of rounding in Python?

Update: Using the guidance from the selected answer, here is the full code solution to my question:

>>> import decimal
>>> decimal.getcontext().rounding = decimal.ROUND_HALF_UP
>>> a = decimal.Decimal("0.745")
>>> round(a, 2)
Decimal('0.75')

Upvotes: 3

Views: 1518

Answers (2)

huu
huu

Reputation: 7472

If you know what precision to round to, you can always add a bit extra to round it how you want (and not necessarily what others would expect):

def round_my_way(dec, precision):
    dec += decimal.Decimal(1.0/10**(precision+1) / 2)
    return round(dec, precision)

print round_my_way(decimal.Decimal("0.746"), 2) # Prints 0.75
print round_my_way(decimal.Decimal("0.745"), 2) # Prints 0.75
print round_my_way(decimal.Decimal("0.744"), 2) # Prints 0.74

Upvotes: 2

Dietrich Epp
Dietrich Epp

Reputation: 213228

That is the expected (and best) behavior: so-called "banker's rounding" which is unbiased and rounds halves to the nearest even whole number.

You can always:

import decimal
decimal.getcontext().rounding = decimal.ROUND_HALF_UP

Note that ROUND_HALF_UP has bias, which is why it's not default.

Upvotes: 6

Related Questions