blob: e244d9c86c3d4fcdd00dbb402b0ae0be9ed5387d [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 */
Gavin Howard6d175b02018-03-09 02:05:07 -070022scale=20
23define e(x){
Gavin Howard97d45122018-03-08 23:44:55 -070024 auto b,s,n,r,d,i,p,f,v
Gavin Howard6d175b02018-03-09 02:05:07 -070025 b=ibase
26 ibase=A
27 if(x<0){
28 n=1
29 x=-x
Gavin Howard97d45122018-03-08 23:44:55 -070030 }
Gavin Howard6d175b02018-03-09 02:05:07 -070031 s=scale
32 r=s+7+0.45*x
33 scale=scale(x)+1
34 while(x>1){
35 d+=1
36 x/=2
37 scale+=1
Gavin Howard97d45122018-03-08 23:44:55 -070038 }
Gavin Howard6d175b02018-03-09 02:05:07 -070039 scale=r
40 r=x+1
41 p=x
Gavin Howardc2762a22018-03-14 12:01:55 -060042 f=v=1
43 for(i=2;v;++i){
Gavin Howard6d175b02018-03-09 02:05:07 -070044 p*=x;
45 f*=i
46 v=p/f
Gavin Howard6d175b02018-03-09 02:05:07 -070047 r+=v
Gavin Howard97d45122018-03-08 23:44:55 -070048 }
Gavin Howard6d175b02018-03-09 02:05:07 -070049 while(f--)r*=r
50 scale=s
51 ibase=b
52 if(m)return(1/r)
53 return(r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -070054}
Gavin Howard6d175b02018-03-09 02:05:07 -070055define l(x){
Gavin Howard538f1412018-03-09 00:35:13 -070056 auto b,s,r,p,a,q,i,v
Gavin Howard6d175b02018-03-09 02:05:07 -070057 b=ibase
58 ibase=A
59 if(x<=0){
60 r=(1-10^scale)/1
61 ibase=b
62 return(r)
Gavin Howard538f1412018-03-09 00:35:13 -070063 }
Gavin Howard6d175b02018-03-09 02:05:07 -070064 s=scale
65 scale+=7
66 p=2
67 while(x>=2){
68 p*=2
69 x=sqrt(x)
Gavin Howard538f1412018-03-09 00:35:13 -070070 }
Gavin Howard6d175b02018-03-09 02:05:07 -070071 while(x<=0.5){
72 p*=2
73 x=sqrt(x)
Gavin Howard538f1412018-03-09 00:35:13 -070074 }
Gavin Howard6d175b02018-03-09 02:05:07 -070075 r=a=(x-1)/(x+1)
76 q=a*a
Gavin Howardc2762a22018-03-14 12:01:55 -060077 v=1
78 for(i=3;v;i+=2){
Gavin Howard6d175b02018-03-09 02:05:07 -070079 n*=m
80 v=n/i
Gavin Howard6d175b02018-03-09 02:05:07 -070081 r+=v
Gavin Howard538f1412018-03-09 00:35:13 -070082 }
Gavin Howard6d175b02018-03-09 02:05:07 -070083 r*=p
84 scale=s
85 ibase=b
86 return(r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -070087}
Gavin Howard6d175b02018-03-09 02:05:07 -070088define s(x){
Gavin Howard3908b972018-03-09 00:38:05 -070089 auto b,s,r,n,a,q,i
Gavin Howard6d175b02018-03-09 02:05:07 -070090 b=ibase
91 ibase=A
92 s=scale
93 scale=1.3*s+2
94 a=a(1)
95 if(x<0){
96 n=1
97 x=-x
Gavin Howard3908b972018-03-09 00:38:05 -070098 }
Gavin Howard6d175b02018-03-09 02:05:07 -070099 scale=0
100 q=(x/a+2)/4
101 x-=4*q*a
102 if(q%2)x=-x
103 scale=s+2
104 r=a=x
105 q=-x*x
Gavin Howardc2762a22018-03-14 12:01:55 -0600106 for(i=3;a;i+=2){
Gavin Howard6d175b02018-03-09 02:05:07 -0700107 a*=q/(i*(i-1))
Gavin Howard6d175b02018-03-09 02:05:07 -0700108 r+=a
Gavin Howard3908b972018-03-09 00:38:05 -0700109 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700110 scale=s
111 ibase=b
112 if(n)return(-r/1)
113 return(r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700114}
Gavin Howard6d175b02018-03-09 02:05:07 -0700115define c(x){
Gavin Howard675f70c2018-03-08 21:19:33 -0700116 auto b,s
Gavin Howard6d175b02018-03-09 02:05:07 -0700117 b=ibase
118 ibase=A
119 s=scale
120 scale+=1
121 x=s(2*a(1)+x)
122 scale=s
123 ibase=b
124 return(x/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700125}
Gavin Howard6d175b02018-03-09 02:05:07 -0700126define a(x){
Gavin Howard96780f32018-03-09 01:27:52 -0700127 auto b,s,r,n,a,m,t,f,i,u
Gavin Howard6d175b02018-03-09 02:05:07 -0700128 b=ibase
129 ibase=A
130 n=1
131 if(x<0){
132 n=-1
133 x=-x
Gavin Howard96780f32018-03-09 01:27:52 -0700134 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700135 if(x==1){
136 if(scale<=64){
Gavin Howard96780f32018-03-09 01:27:52 -0700137 return(.7853981633974483096156608458198757210492923498437764552437361480/n)
138 }
139 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700140 if(x==.267){
141 if(scale<=64){
Gavin Howard96780f32018-03-09 01:27:52 -0700142 return(.2609135692329405795967852677779865639774740239882445822329882917/n)
143 }
144 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700145 s=scale
146 if(x>.267){
147 scale+=5
148 a=a(.267)
Gavin Howard96780f32018-03-09 01:27:52 -0700149 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700150 scale=s+3
151 while(x>.267){
152 m+=1
153 x=(x-.267)/(1+.267*x)
Gavin Howard96780f32018-03-09 01:27:52 -0700154 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700155 r=u=x
156 f=-x*x
Gavin Howardc2762a22018-03-14 12:01:55 -0600157 t=1
158 for(i=3;t;i+=2){
Gavin Howard6d175b02018-03-09 02:05:07 -0700159 u*=f
160 t=u/i
Gavin Howard6d175b02018-03-09 02:05:07 -0700161 r+=t
Gavin Howard96780f32018-03-09 01:27:52 -0700162 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700163 scale=s
164 ibase=b
165 return((m*a+r)/n)
Gavin Howard140a3432018-03-08 23:13:05 -0700166}
Gavin Howard6d175b02018-03-09 02:05:07 -0700167define j(n,x){
Gavin Howarddb919392018-03-09 01:00:26 -0700168 auto b,s,o,a,i,v,f
Gavin Howard6d175b02018-03-09 02:05:07 -0700169 b=ibase
170 ibase=A
171 s=scale
172 scale=0
173 n/=1
174 if(n<0){
175 n=-n
176 if(n%2==1)o=1
Gavin Howarddb919392018-03-09 01:00:26 -0700177 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700178 a=1
179 for(i=2;i<=n;++i)f*=i
180 scale=1.5*s
181 a=(x^n)/(2^n*a)
182 r=v=1
183 f=-x*x/4
184 scale+=length(a)-scale(a)
Gavin Howardc2762a22018-03-14 12:01:55 -0600185 for(i=1;v;++i){
Gavin Howard6d175b02018-03-09 02:05:07 -0700186 v=v*s/i/(n+i)
Gavin Howard6d175b02018-03-09 02:05:07 -0700187 r+=v
Gavin Howarddb919392018-03-09 01:00:26 -0700188 }
Gavin Howard6d175b02018-03-09 02:05:07 -0700189 scale=s
190 ibase=b
191 if(o)return(-a*r/1)
192 return(a*r/1)
Gavin Howard675f70c2018-03-08 21:19:33 -0700193}