Reputation: 19780
If I do the following, I would expect 0.005
to be rounded up to 0.01
instead of down to 0.00
because rounding was set to ROUND_HALF_UP.
>>> import decimal
>>> currency = decimal.Context(rounding=decimal.ROUND_HALF_UP)
>>> cents = decimal.Decimal('0.00')
>>> amount = currency.create_decimal('0.005')
>>> amount
Decimal('0.005')
>>> amount.quantize(cents)
Decimal('0.00')
But if I pass currency to quantize()
, it rounds properly:
>>> amount.quantize(cents, context=currency)
Decimal('0.01')
Why does amount (which was created from the currency context) not round using the currency context?
NOTE: This question is not asking how to round to 2 decimal places. I am merely using that as an example. I would like to know why a Decimal
created from a Context
does not use that same Context
when quantizing/rounding.
Upvotes: 2
Views: 4191
Reputation: 281843
Decimal objects do not retain the context they were created from. Decimal operations that use a specific context, such as Context.create_decimal
or Decimal.quantize
with a context argument, only override the global context for that one operation; further operations on the resulting Decimal are done with the global context.
If you want to have all operations use ROUND_HALF_UP
, you can set the global context:
decimal.setcontext(currency)
but if you want to mix contexts, you'll have to provide a context explicitly for every operation that needs a context other than the global context.
Upvotes: 6
Reputation: 653
You need to set the context using decimal.setcontext()
or pass it to quantize()
function as a keyword argument to work properly.
>>> import decimal
>>> currency = decimal.Context(rounding=decimal.ROUND_HALF_UP)
>>> decimal.setcontext(currency) # setting the context
>>> cents = decimal.Decimal('0.00')
>>> amount = currency.create_decimal('0.005')
>>> amount.quantize(cents)
Decimal('0.01')
Setting the context globally using decimal.getcontext().rounding = decimal.ROUND_HALF_UP
works fine as well, but then it will be use for all future operations with any Decimal
.
>>> import decimal
>>> decimal.getcontext().rounding = decimal.ROUND_HALF_UP
>>> cents = decimal.Decimal('0.00')
>>> amount = decimal.Decimal('0.005')
>>> amount.quantize(cents)
Decimal('0.01')
Upvotes: 1