Sign up ×

I am looking into rounding floating point numbers in Python and the following behavior seems quite strange:


a = 203.25
print '%.2f'%(a/10.)
print '%.2f'%(round(a/10., 2))
print '%.2f'%(0.1*a)



Why does the first and especially the second case fail?

share|improve this question

6 Answers 6

up vote 7 down vote accepted

Round half to even
A tie-breaking rule that is less biased is round half to even, namely:

If the fraction of y is 0.5, then q is the even integer nearest to y. Thus, for example, +23.5 becomes +24, as does +24.5; while −23.5 becomes −24, as does −24.5.

This method treats positive and negative values symmetrically, and is therefore free of sign bias. More importantly, for reasonable distributions of y values, the expected (average) value of the rounded numbers is the same as that of the original numbers. However, this rule will introduce a towards-zero bias for even numbers, and a towards-infinity bias for odd ones.

This variant of the round-to-nearest method is also called unbiased rounding, convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, odd-even rounding or bankers' rounding, and is widely used in bookkeeping.

This is the default rounding mode used in IEEE 754 computing functions and operators.

>>> "%.2f"%20.325
>>> "%.2f"%20.335
>>> "%.2f"%20.345
>>> "%.2f"%20.355

So the real question should be why does the third case fail?

203.25 can be expressed exactly in the floating point representation, however 0.1 cannot, it turns out to be a tiny bit more than 0.1

>>> 0.1*203.25

So it gets rounded up

share|improve this answer
+1 for the wikipedia ref. – Burhan Khalid Sep 4 '12 at 7:48

This probably is part of the answer:

>>> a*.1
>>> a/10

See @gnibblers explanation about how IEEE 754 rounding is implemented.

share|improve this answer

I don't know the specific details about why those cases don't work as expected, but if you want strict accuracy with your floats, use something like the decimal module.

share|improve this answer

You can use printf to see what's happening

 print '%0.20f'%20.325
share|improve this answer

The Python docs for round() point to the answer. Basically, floating point can't represent some numbers exactly. For instance, 0.1 ends up looking like 0.10000000000000001. This imprecision can sometimes lead to unexpected results. It's really quite difficult to get calculations within a given range of tolerance with floating point numbers. The reason the 0.1 * a calculation works in your case, is because it's ever so slightly biased in your desired direction of rounding.

If you really need precision, you should look at using the Decimal module. Working with decimal numbers can also be a chore, but it does make it a bit easier to get the precision you desire.

share|improve this answer

Your Answer


