1from decimal import Decimal, getcontext
2import math
3
4
[docs]
5def decimal_pi() -> Decimal:
6 getcontext().prec += 2
7 three = Decimal(3)
8 lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
9 while s != lasts:
10 lasts = s
11 n, na = n + na, na + 8
12 d, da = d + da, da + 32
13 t = (t * n) / d
14 s += t
15 getcontext().prec -= 2
16 return +s
17
18
[docs]
19def decimal_exp(x: Decimal) -> Decimal:
20 getcontext().prec += 2
21 i, lasts, s, fact, num = 0, 0, 1, 1, 1
22 while s != lasts:
23 lasts = s
24 i += 1
25 fact *= i
26 num *= x
27 s += num / fact
28 getcontext().prec -= 2
29 return +s
30
31
[docs]
32def decimal_cos(x: Decimal) -> Decimal:
33 getcontext().prec += 2
34 i, lasts, s, fact, num, sign = 0, 0, 1, 1, 1, 1
35 while s != lasts:
36 lasts = s
37 i += 2
38 fact *= i * (i - 1)
39 num *= x * x
40 sign *= -1
41 s += num / fact * sign
42 getcontext().prec -= 2
43 return +s
44
45
[docs]
46def decimal_sin(x: Decimal) -> Decimal:
47 getcontext().prec += 2
48 i, lasts, s, fact, num, sign = 1, 0, x, 1, x, 1
49 while s != lasts:
50 lasts = s
51 i += 2
52 fact *= i * (i - 1)
53 num *= x * x
54 sign *= -1
55 s += num / fact * sign
56 getcontext().prec -= 2
57 return +s
58
59
[docs]
60def decimal_asin(x: Decimal) -> Decimal:
61 assert isinstance(x, Decimal)
62 if x < -1 or x > 1:
63 raise ValueError("math domain error")
64 if x == 1:
65 return decimal_pi() / 2
66 if x == -1:
67 return -decimal_pi() / 2
68 getcontext().prec += 2
69 eps = Decimal("1e-" + str(getcontext().prec))
70 sum_acos = x
71 term = Decimal(1)
72 power = x
73 n = 0
74 while abs(term * power) > eps:
75 n += 1
76 term *= (2 * n - 1) * (2 * n) * (2 * (n - 1) + 1)
77 term /= 4 * n * n * (2 * n + 1)
78 power *= x * x
79 sum_acos += term * power
80 result = sum_acos
81 getcontext().prec -= 2
82 return +result
83
84
[docs]
85def decimal_acos(x: Decimal) -> Decimal:
86 assert isinstance(x, Decimal)
87 if x < -1 or x > 1:
88 raise ValueError("math domain error")
89 if x == 1:
90 return Decimal(0)
91 if x == -1:
92 return decimal_pi()
93 getcontext().prec += 2
94 eps = Decimal("1e-" + str(getcontext().prec))
95 sum_acos = x
96 term = Decimal(1)
97 power = x
98 n = 0
99 while abs(term * power) > eps:
100 n += 1
101 term *= (2 * n - 1) * (2 * n) * (2 * (n - 1) + 1)
102 term /= 4 * n * n * (2 * n + 1)
103 power *= x * x
104 sum_acos += term * power
105 result = decimal_pi() / 2 - sum_acos
106 getcontext().prec -= 2
107 return +result