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