[Python-ideas] Python Numbers as Human Concept Decimal System

Ron Adam ron3200 at gmail.com
Sun Mar 9 15:28:53 CET 2014



On 03/09/2014 07:36 AM, Stefan Krah wrote:
> Steven D'Aprano<steve at 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)


Or even...

     setcontext(CALCULATOR)


>> > So I must admit, I'm not sure where the extra digits come from:
>> >
>> > Decimal('9017.01098128643570817075669765472412109375')
>> > Decimal('9017.010981286435708170756694')

> 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)

Cheers,
    Ron



More information about the Python-ideas mailing list