Setting longer default decimal precision

Oscar Benjamin oscar.j.benjamin at gmail.com
Wed Nov 20 09:40:36 EST 2013


On 20 November 2013 14:02, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
>
> but alas, all the functions in the math module convert their arguments to
> float first, so even though your Decimal(1) could perform calculations to
> 75 decimal places, the math.atan function downgrades it to a regular
> float.
>
> Unfortunately, Decimals don't support high-precision trig functions. If
> you study the decimal.py module, you could possibly work out how to add
> support for trig functions, but they have no current support for them.

The documentation has examples for how to make high precision sin()
and cos() functions that work with Decimals.
http://docs.python.org/2/library/decimal.html#recipes

The basic idea is to sum terms of the Maclaurin series until it
converges. For atan(x) the Maclaurin series is

atan(x) = x - (1/3)x**3 + (1/5)x**5 - (1/7)x**7 + (1/9)x**9 + ...

The nth term is given by f(n) = ((-1)**n)*(1/(2n+1))*x**(2n+1).

The ratio test gives that that |f(n+1)/f(n)| = (2(n+1)+1)/(2n + 1) *
x**2 which has a limiting value of x**2 so the series converges for
|x| < 1 (unlike sin() and cos() that converge for all x). For values
outside this range you can use the identity arctan(1/x) ==
sign(x)*pi/2 - arctan(x) to map the values back into the convergent
range. This may still be problematic when x is close to 1 in which
case an alternate Taylor series around x=1 could be used. You'd need
to ensure that you were using enough digits for pi as well if you
wanted to make this work.

It's probably easiest just to use the mpmath library as Steven
suggested (or gmpy2, or sympy which includes mpmath).


Oscar



More information about the Python-list mailing list