[issue21929] Rounding properly

Mark Dickinson report at bugs.python.org
Mon Jul 7 14:00:27 CEST 2014


Mark Dickinson added the comment:

This is working as designed, though admittedly the cause of the unexpected results is non-obvious.

In Python 2, there's no way to implement `round` for a general type:  instead, the `round` function converts its *input* to a Python (binary) float, and then rounds the resulting value.  So you're effectively doing:

>>> from decimal import Decimal
>>> round(float(Decimal('167.75')), 1)
167.8
>>> round(float(Decimal('167.85')), 1)
167.8
>>> round(float(Decimal('167.95')), 1)
167.9

And the results above are explainable in terms of rounding the corresponding floating-point value:  the closest exactly representable binary float to 167.85 is 167.849999999999994315658113919198513031005859375, which is a touch less than the halfway mark, so rounds down.  Similarly, the closest exactly representable float to 167.95 is 167.94999999999998863131622783839702606201171875, which again rounds down.  167.75 is already exactly representable as a float, so there you get the expected result.

In Python 3, `round` rounds the Decimal object directly without converting to float first, so you shouldn't see the above problems.  In Python 2, you'll need to stick to your quantize approach.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue21929>
_______________________________________


More information about the Python-bugs-list mailing list