extend methods of decimal module

Oscar Benjamin oscar.j.benjamin at gmail.com
Thu Feb 27 15:42:55 CET 2014


On 27 February 2014 12:07, Mark H. Harris <harrismh777 at gmail.com> wrote:
>
> I have created a project here:
>
> https://code.google.com/p/pythondecimallibrary/
>
> I wrote a dmath.py library module for use with the C accelerated decimal module, that I would like to see merged into the C Python distribution so that folks have it by default... without having to pull it down with GIT, or whatever.

Hi Mark,

Some points:

1) Why have you committed the code as a .tar.gz file?

2) This function is not such a good idea:
def D(numform):
    return Decimal(str(numform))
The Decimal constructor already accepts strings and many types of
numbers. Going via str like this reduces accuracy if e.g. someone
passes a float in.

3) In many places you've written code like this:
    prec=dscale(getcontext().prec +7)
    sqr = (D(x).sqrt()).__round__(prec)
    retscale=dscale(prec)

The preferred way is:
    with localcontext() as ctx:
        ctx.prec += 7
        sqr = round(D(x).sqrt(), prec)

i.e. use a context manager to restore the context even if an error
occurs and use the round builtin rather than the dunder method.

4) You shouldn't be using round/__round__ for precision rounding: it
uses decimal places rather than significant figures. If you want to
round to context precision just use unary +. i.e.:
    return +sqr

5) The Decimal.sqrt method already rounds to context precision.
There's no need to compute in higher precision and then round it
yourself (in fact you're invalidating the correctness of the rounding
by double-rounding like this). So really it's just:
    def sqrt(x):
        return Decimal(x).sqrt()

6) You should organise it in such a way that you're not progressively
increasing the precision each time one function calls another.


Oscar



More information about the Python-list mailing list