Python's percent-style formatting doesn't understand Decimal objects: when you format, there's an implicit conversion to float. It just so happens that the nearest representable binary float to your x value is this:
>>> print Decimal(float(x))
111.1650000000000062527760746888816356658935546875
That's a touch greater than the 111.165 halfway case, so it rounds up. Similarly, for y, the value that ends up being formatted is this one:
>>> print Decimal(float(y))
236.164999999999992041921359486877918243408203125
In that case, the value being formatted for output is just below the halfway value, so it rounds down.
To avoid the implicit conversion, you can use the .format formatting method:
>>> "{0:.2f}".format(Decimal('111.1650'))
'111.16'
>>> "{0:.2f}".format(Decimal('236.1650'))
'236.16'
Note that you still might not like all the results, though:
>>> "{0:.2f}".format(Decimal('236.1750'))
'236.18'
This style of formatting uses the round-half-to-even rounding mode by default. In fact, it takes the 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')) # Now rounds up!
'236.17'
As a general comment, being able to implement custom formatting for user-defined classes is one of the big wins for the new-style .format formatting method over the old-style %-based formatting.