Percentage formatting in the Python style does not understand Decimal objects: when formatting, an implicit conversion to float occurs. It so happens that the closest binary binary float to your x value is:
>>> print Decimal(float(x)) 111.1650000000000062527760746888816356658935546875
This touch is larger than 111.165 halfway, so it is rounded. Similarly, for y value that ends with formatting is as follows:
>>> print Decimal(float(y)) 236.164999999999992041921359486877918243408203125
In this case, the value formatted for the output is slightly lower than the halfway value, so it is rounded down.
To avoid implicit conversion, you can use the .format formatting .format :
>>> "{0:.2f}".format(Decimal('111.1650')) '111.16' >>> "{0:.2f}".format(Decimal('236.1650')) '236.16'
Please note that you may still not like all the results:
>>> "{0:.2f}".format(Decimal('236.1750')) '236.18'
This formatting style uses a rounded rounded rounding mode by default. In fact, it takes a rounding mode from the current Decimal context, so you can do this:
>>> from decimal import getcontext, ROUND_HALF_UP >>> getcontext().rounding=ROUND_HALF_UP >>> "{0:.2f}".format(Decimal('236.1750')) '236.18' >>> "{0:.2f}".format(Decimal('236.1650'))
As a general note, the ability to implement custom formatting for custom classes is one of the big gains for the new .format formatting method compared to the old-style % formatting.
source share