[Python-Dev] Adventures with Decimal

Raymond Hettinger python at rcn.com
Wed May 18 08:03:07 CEST 2005


[Raymond]
> > The following example shows the kind of oddity that can arise when
> > working with quantities that have not been rounded to the current
> precision:
> >
> > >>> from decimal import getcontext, Decimal as D
> > >>> getcontext().prec = 3
> > >>> D('3.104') + D('2.104')
> > Decimal("5.21")
> > >>> D('3.104') + D('0.000') + D('2.104')
> > Decimal("5.20")

[Tim]
> I think it shows more why it was a mistake for the decimal constructor
> to extend the standard (the string->decimal operation in the standard
> respects context settings; the results differ here because D(whatever)
> ignores context settings;

For brevity, the above example used the context free constructor, but
the point was to show the consequence of a precision change.  That
oddity occurs even in the absence of a call to the Decimal constructor.
For instance, using the context aware constructor,
Context.create_decimal(), we get the same result when switching
precision:


>>> from decimal import getcontext
>>> context = getcontext()
>>> x = context.create_decimal('3.104')
>>> y = context.create_decimal('2.104')
>>> z = context.create_decimal('0.000')
>>> context.prec = 3
>>> x + y
Decimal("5.21")
>>> x + z + y
Decimal("5.20")

The whole point of the unary plus operation in the decimal module is to
force a rounding using the current context.  This needs to be a standard
practice whenever someone is changing precision in midstream.  Most
folks won't (or shouldn't) be doing that, but those who do (as they
would in the PEP's use case) need a unary plus after switching
precision.

As for why the normal Decimal constructor is context free, PEP 327
indicates discussion on the subject, but who made the decision and why
is not clear. 



Raymond


More information about the Python-Dev mailing list