Welcome, guest | Sign In | My Account | Store | Cart

Implementation of sine, cosine, tangent functions for Decimal arithmetic, using Taylor series expansion. It uses simple numerator and denominator generators.

The nice part is, the code is independent from the Decimal library. Feed it a float, it works just the same as if you feed it a Decimal (apart from the precision :-)

Python, 64 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from decimal import *
import math

pi = Decimal("3.14159265358979323846264338327950288419716939937510")

def gen_den():
    d = 1
    f = 1
    while(1):
        yield f
        d = d + 1
        f = f * d
    return

def gen_num(x):
    n = x
    while(1):
        yield n
        n *= x
    return

def gen_sign():
    while(1):
        yield 1
        yield -1
        yield -1
        yield 1
    return

def sincos(x):
    x = divmod(x, 2 * pi)[1]
    den = gen_den()
    num = gen_num(x)
    sign = gen_sign()

    s = 0
    c = 1
    i = 1
    done_s = False; done_c = False

    while(not done_s and not done_c):
        new_s = s + sign.next() * num.next() / den.next()
        new_c = c + sign.next() * num.next() / den.next()
        if (new_c - c == 0): done_c = True
        if (new_s - s == 0): done_s = True
        c = new_c
        s = new_s
        i = i + 2
    return (s, c)

def dec_sin(x):
    (s, c) = sincos(x)
    return s

def dec_cos(x):
    (s, c) = sincos(x)
    return c

def dec_tan(x):
    (s, c) = sincos(x)
    return s/c

print dec_sin(Decimal(1234))
print math.sin(1234)

Use it with:

from decimal import *

dec_sin(Decimal("0.5"))

3 comments

Gabriel Genellina 16 years, 9 months ago  # | flag

Chebyshev polynomials may be faster. The problem with Taylor series in this case, is that it converges very slowly. A Chebyshev polynomial requires far less terms to obtain a desired precision, and can be generated using similar recurrence relations like your code for Taylor terms. See http://en.wikipedia.org/wiki/Chebyshev_approximation#Chebyshev_approximation

Raymond Hettinger 16 years, 9 months ago  # | flag

Alternate recipes. Compare with the recipes already given in the docs:

http://docs.python.org/lib/decimal-recipes.html

Alain Mellan (author) 16 years, 9 months ago  # | flag

Thanks. I should have Googled more before writing the code :-)

OTOH, generators are fun!