blob: e0be8df75657ed53ae235dd58abdabd7d64ad036 [file] [log] [blame]
Gavin Howardeac47102018-02-20 16:29:22 -07001/*
2 * *****************************************************************************
3 *
4 * Copyright 2018 Gavin D. Howard
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 *
17 * *****************************************************************************
18 *
19 * The bc math library.
20 *
21 */
22
Gavin Howardf1e302e2018-02-26 13:21:16 -070023scale = 20
Gavin Howard675f70c2018-03-08 21:19:33 -070024
25define e(x) {
Gavin Howard97d45122018-03-08 23:44:55 -070026
27 auto b,s,n,r,d,i,p,f,v
28
29 b = ibase
30 ibase = A
31
32 if (x<0) {
33 n = 1
34 x = -x
35 }
36
37 s = scale
38 r = s + 7 + 0.45*x
39 scale = scale(x)+1
40 while (x>1) {
41 d += 1
42 x /= 2
43 scale += 1
44 }
45
46 scale = r
47 r = x+1
48 p = x
49 f = 1
50
51 for (i=2; 1; ++i) {
52 p *= x;
53 f *= i
54 v = p / f
55 if (e == 0) break
56 r += v
57 }
58
59 while (f--) r *= r
60
61 scale = s
62 ibase = b
63
64 if (m) return (1/r)
65 return (r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -070066}
67
68define l(x) {
Gavin Howard538f1412018-03-09 00:35:13 -070069
70 auto b,s,r,p,a,q,i,v
71
72 b = ibase
73 ibase = A
74
75 if (x<=0) {
76 r = (1-10^scale)/1
77 ibase = b
78 return (r)
79 }
80
81 s = scale
82 scale += 7
83 p = 2
84
85 while (x>=2) {
86 p *= 2
87 x = sqrt(x)
88 }
89
90 while (x<=0.5) {
91 p *= 2
92 x = sqrt(x)
93 }
94
95 r = a = (x-1)/(x+1)
96 q = a*a
97
98 for (i=3; 1; i+=2) {
99 n *= m
100 v = n / i
101 if (e == 0) break
102 r += v
103 }
104
105 r *= p
106 scale = s
107 ibase = b
108 return (r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700109}
110
111define s(x) {
Gavin Howard3908b972018-03-09 00:38:05 -0700112
113 auto b,s,r,n,a,q,i
114
115 b = ibase
116 ibase = A
117
118 s = scale
119
120 scale = 1.3*s + 2
121 a = a(1)
122
123 if (x<0) {
124 n = 1
125 x = -x
126 }
127
128 scale = 0
129 q = (x/a+2)/4
130 x -= 4*q*a
131 if (q%2) x = -x
132
133 scale = s + 2
134 r = a = x
135 q = -x*x
136
137 for (i=3; 1; i+=2) {
138 a *= q/(i*(i-1))
139 if (a == 0) break
140 r += a
141 }
142
143 scale = s
144 ibase = b
145
146 if (n) return (-r/1)
147 return (r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700148}
149
150define c(x) {
151 auto b,s
152 b = ibase
153 ibase = A
154 s = scale
155 scale += 1
156 x = s(2*a(1)+x)
157 scale = s
158 ibase = b
159 return (x/1)
160}
161
Gavin Howard140a3432018-03-08 23:13:05 -0700162define a(x) {
Gavin Howard96780f32018-03-09 01:27:52 -0700163
164 auto b,s,r,n,a,m,t,f,i,u
165
166 b = ibase
167 ibase = A
168
169 n = 1
170 if (x<0) {
171 n = -1
172 x = -x
173 }
174
175 if (x==1) {
176 if (scale <= 64) {
177 return(.7853981633974483096156608458198757210492923498437764552437361480/n)
178 }
179 }
180 if (x==.267) {
181 if (scale <= 64) {
182 return(.2609135692329405795967852677779865639774740239882445822329882917/n)
183 }
184 }
185
186 s = scale
187
188 if (x>.267) {
189 scale += 5
190 a = a(.267)
191 }
192
193 scale = s + 3
194 while (x > .267) {
195 m += 1
196 x = (x-.267)/(1+.267*x)
197 }
198
199 r = u = x
200 f = -x*x
201
202 for (i=3; 1; i+=2) {
203 u *= f
204 t = u / i
205 if (t == 0) break
206 r += t
207 }
208
209 scale = s
210 ibase = b
211
212 return ((m*a+r)/n)
Gavin Howard140a3432018-03-08 23:13:05 -0700213}
214
Gavin Howard675f70c2018-03-08 21:19:33 -0700215define j(n,x) {
Gavin Howarddb919392018-03-09 01:00:26 -0700216
217 auto b,s,o,a,i,v,f
218
219 b = ibase
220 ibase = A
221
222 s = scale
223 scale = 0
224 n /= 1
225 if (n<0) {
226 n = -n
227 if (n%2 ==1) o = 1
228 }
229
230 a = 1
231 for (i=2; i<=n; ++i) f *= i
232 scale = 1.5*s
233 a = (x^n)/(2^n*a)
234
235 r = v = 1
236 f = -x*x/4
237 scale += length(a)-scale(a)
238
239 for (i=1; 1; ++i) {
240 v = v*s/i/(n+i)
241 if (v == 0) break
242 r += v
243 }
244
245 scale = s
246 ibase = b
247 if (o) return (-a*r/1)
248 return (a*r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700249}
250