Reputation: 44401
I was expecting 2 decimal precission, but:
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 2
>>> Decimal(98791.4913)
Decimal('98791.491299999994225800037384033203125')
>>> getcontext()
Context(prec=2, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
Why is Decimal
not honoring the Context
precission?
Upvotes: 1
Views: 205
Reputation: 46563
From the documentation:
If value is a float, the binary floating point value is losslessly converted to its exact decimal equivalent. This conversion can often require 53 or more digits of precision. For example,
Decimal(float('1.1'))
converts toDecimal('1.100000000000000088817841970012523233890533447265625')
.The context precision does not affect how many digits are stored. That is determined exclusively by the number of digits in value.
...
Context precision and rounding only come into play during arithmetic operations.
Emphasis mine.
You can truncate the value by using the Decimal.quantize
method:
places = 2
Decimal(98791.4913).quantize(Decimal(10) ** -places) # 98791.49
or the Context.quantize
:
places = 2
getcontext().quantize(Decimal(98791.4913), Decimal(10) ** -places) # 98791.49
Upvotes: 2
Reputation: 90979
Quoting from documentation (Emphasis mine) -
If value is a float, the binary floating point value is losslessly converted to its exact decimal equivalent. This conversion can often require 53 or more digits of precision. For example, Decimal(float('1.1')) converts to Decimal('1.100000000000000088817841970012523233890533447265625').
The context precision does not affect how many digits are stored. That is determined exclusively by the number of digits in value. For example, Decimal('3.00000') records all five zeros even if the context precision is only three.
The purpose of the context argument is determining what to do if value is a malformed string. If the context traps InvalidOperation, an exception is raised; otherwise, the constructor returns a new Decimal with the value of NaN.
And from same documentation -
The significance of a new Decimal is determined solely by the number of digits input. Context precision and rounding only come into play during arithmetic operations.
Great examples given in the documentation -
>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')
Upvotes: 5