[Tutor] How to correct decimal addition.
Oscar Benjamin
oscar.j.benjamin at gmail.com
Sat Jan 25 23:09:56 CET 2014
On 25 January 2014 21:38, Keith Winston <keithwins at gmail.com> wrote:
>
> Also, just to be clear: I'd suggest floats because decimal requires
> importing a module and using the non-built-in features thereof,
Importing a module is not something to be afraid of. Python comes with
loads of modules especially so you can import them! :P
Also as of CPython 3.3 the decimal module is rewritten in C (which is
what is normally meant by "built-in").
> especially if you're going to do something like
> decimal.getcontext().prec (even that doesn't set precision AFTER the
> decimal point... only total precision). My point being that I don't
> see the value of sending a beginner into that morass.
Maybe it's tricky for a beginner. It is however good advice that you
should not use binary floating point for financial calculations.
> I actually still
> can't find how to force decimal to round to 3 places after the
> decimal...
I find myself using this:
>>> from decimal import Decimal as D
>>> D('0.1234567').quantize(D('1.000'))
Decimal('0.123')
Perhaps it would be better though to point at this:
>>> round(D('0.123456'), 3)
Decimal('0.123')
> (actually, I can't find a single reference to .prec except
> in examples in the standard library doc of decimal
> http://docs.python.org/3.3/library/decimal.html#decimal.getcontext)
.prec is "significant figures" rather than "decimal places" so it's
not what you want here.
> And finally: when I said "watch out for rounding", I meant be prepared
> for it. It is correct that rounding happens (otherwise the Snopes
> Salami scam happens), and I can't imagine that at the level at which
> the OP is working, any subtle control over rounding will be important
> (i.e. ROUNDING_CEILING or any such thing).
Some calculations need rounding in any fixed-width floating point
system. The decimal module let's you go up to 425 million digits
though:
>>> from decimal import MAX_PREC
>>> MAX_PREC
425000000
More importantly it has traps that you can use to catch any example of
inexact computation:
>>> from decimal import localcontext, Inexact
>>> with localcontext() as ctx:
... ctx.traps[Inexact] = True
... D(1) / 3
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
decimal.Inexact: [<class 'decimal.Inexact'>]
This way you can feel confident that your results are exact or else
you'd have seen an error message.
Oscar
More information about the Tutor
mailing list