prePEP: Decimal data type

Bengt Richter bokr at
Wed Nov 5 01:09:46 CET 2003

On Tue, 4 Nov 2003 15:26:35 -0300, "Batista, Facundo" <FBatista at> wrote:
>#-     I.e., '1.1' means something different from '1.1000',=20
>#- even though hopefully
>#-     Decimal('1.1')=3D=3DDecimal('1.1000').
>Decimal('1.1') =3D=3D Decimal('1.1000') =3D=3D Decimal(11) / =
Yes, but what about 
 Decimal('1.1')/Decimal('3') =?=> Decimal('0.4')
 Decimal('1.1000')/Decimal('3') =?=> Decimal('0.3667')
 (Decimal(11)/Decimal(10))/Decimal('3') =?=> Decimal('0.4')

so e.g.,
 Decimal('1.1')/Decimal('3') !(?)= Decimal('1.1000')/Decimal('3')

Or is the "Context" thing defining what all the "Decimal" constructions above do,
and extra zeroes in a literal may be ignored?

(If so, how does a "Decimal" know what "Context" to refer to if you have more than
one "Context" going? -- IOW why wouldn't you take Decimal+Context => Decimal subclass,
and let the sublass instance find its "Context" info by way of its inheritance instead
of some other Decimal<->Context association?

I guess I am missing the "Context" info, sorry. Where is its relation to Decimal defined?

>#- >1. The syntax should be ``Decimal(value)``.
>#-     Decimal(value, precision_info) when the value cannot be=20
>#- presumed exact, IWT.
>#- >
>#- >2. The value could be of the type:
>#- >
>#- >       - another Decimal
>#-           presume this is just a copy, unless precision info=20
>#- is provided?
>That's right.
>#- >       - int or long
>#-           assume no-fractional-bits precision?
>Remember that the precision is in the context.
Sorry, how is context defined, so as to be accessed by the Decimal constructor?
Or is there a metaclass that modifies Decimal with custom context?

>#-           even if there is an exponent? I.e., what does=20
>#- '1.000e3' mean? Same as '1000' or
>#-           '1000.000' ? What about '1.000e-2' ? Same as=20
>#- '0.010' or as '0.01' ?
>Decimal('1.000e3') =3D=3D Decimal('1000') =3D=3D Decimal('1000.000')=20
>Decimal('1.000e-2') =3D=3D Decimal('0.010') =3D=3D Decimal('0.01')=20
>as a human can tell! :)
Well, I meant same in a broader sense, as in will it act the same? E.g., will
the result of dividing them each by Decimal('3') have the same (equal) results?
If not, then they may be equal before dividing, but they're not the same.

>#- Maybe there needs to be an abstract base class that you=20
>#- _have_ to subclass and
>#- specify all these things?
>You just specify in the context what type of rounding you want. And =
I guess I need a pointer to the context definition. I didn't wind up with a clear concept.
I probably was falling asleep or something. I guess I should re-read ;-/
>#- >       m =3D Decimal(...)
>#- >       m =3D=3D eval(repr(m))
>#- Does that mean repr(m) will always look like=20
>#- "Decimal('<string literal>')" ?
>Still don't know.
Ok, fair enough ;-)

>#- But what about rules for precision promotion -- i.e., if you add
>#- Decimal('1.1') and Decimal('0.05') I would expect the result=20
>#- to have the
>#- more precise precision, and repr like "Decimal('1.15')"
>Remember the precision is in the context, not in each instance.=20
Again, how does Decimal find whatever context it should get precision from?

>#- I have a hunch (a*b)*c could sometimes come out different=20
>#- from a*(b*c)
>#- if rounding-to-specified-precision is imposed at every operation.
>This can happen, as with all the roundings data types.
Isn't this a fairly subtle thing to expect programmers to realize, who you will
be trying to make things easy for with a Money class based on this stuff?

Of course, you could use this stuff at very high precision, and then implement
a class with Currency properties that would appear to enforce precision rounding
only on assignment, and appear to evaluate rhs expressions with (for practical purposes)
infinite precision. IMO that might be easier to think about. Right hand side expressions
would seem continuously mathematically accurate, and assignments would choose the discrete
quantized values. Then rules would be on theoretical values mapped at controlled times, and
the problem would be making sure that enough precision was carried to guarantee
as-if-infinite-precision rounding results (and presumably raising an exception if that
broke down). This sounds like interval math in disguise kind of, but maybe it's not that
bad in practical contexts?

>Anyway, you always can set the "rounding" trap in the context to raise =
Assuming you get a call to a handler from the middle of an expression evaluation,
what would you do? Seems like subtle programming decisions either to document or
pass the buck on in an EZMoney module built on this ;-)

Bengt Richter

More information about the Python-list mailing list