On 03/09/2014 07:36 AM, Stefan Krah wrote:
Steven D'Apranosteve@pearwood.info wrote:
Note that this round-trips back to float correctly:
py> assert float(d) == 9017.010981286436
Many inexact values map to the same float.
To get the same result as Stevens calculation, the context needs to be set to 16.
from decimal import * setcontext(Context(16)) Decimal(2478577105427079) / 274877906944 Decimal('9017.010981286436')
When converting a float to Decimal... shouldn't the smallest (closest to zero) value that round trips be correct? It seems like anything else is an implicit rounding up. We don't add .5 when we convert an int to a float.
The rounding may be due to the financial need to average out small errors rather than have them accumulate. ie.. ROUND_HALF_EVEN,
from decimal import * getcontext() Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=, traps=[InvalidOperation, DivisionByZero, Overflow])
Which is why it's suggested decimal should only be used for financial calculations. But it's only the context that differs I think. Decimals default context does seem to be for financial calculations. Maybe there should be some easy to set contexts could be added.
setcontext(MATH) setcontext(FINANCE) setcontext(SCIENCE)
So I must admit, I'm not sure where the extra digits come from:
Without looking at your calculation, I guess it is rounding:
> 9017.010981286436.as_integer_ratio() (2478577105427079, 274877906944) > Decimal(2478577105427079) / 274877906944 Decimal('9017.010981286435708170756698') > getcontext().prec = 100 > Decimal(2478577105427079) / 274877906944 Decimal('9017.01098128643570817075669765472412109375')
Something that bothers me about the decimal module is how the rest of the numbers are converted. (Not the ones entered in by hand.)
If we should enter x = Decimal('some number') to get the exact value, how does Decimal get y in xy = x * y if y is a float? Would it be the same as Decimal(y)? (Without quotes)