aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--bc.library277
2 files changed, 282 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..86f57d8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
1This is a small collection of mathematical functions for bc(1),
2the standard UNIX basic calculator.
3
4To use them, copy `bc.library` in a convenient location and call
5bc with `bc /path/to/bc.library`.
diff --git a/bc.library b/bc.library
new file mode 100644
index 0000000..6b94a01
--- /dev/null
+++ b/bc.library
@@ -0,0 +1,277 @@
1/*
2 * The content of this file is free knowledge.
3 * No copyright applies. No warranty is provided.
4 *
5 * The following functions are available (aliases in parentheses):
6 * General utility: max, min, sgn, abs, floor, ceiling
7 * Arithmetic: factorial(fact), binomial(binom, bin), gcd, lcm, totient(phi)
8 * Calculus: exp, log(ln), pow, sin, cos, tan, cosh, sinh, tanh
9 * atan, atan2, asin, acos, atanh, asinh, acosh
10 * Constants (as functions): e(), pi()
11 *
12 * Approximation of inverse trigonometric functions and of pi is not good.
13 *
14 * For functions returning non-integer values, remember to set the
15 * desired scaled value before calling the function.
16 */
17
18/* General utility functions */
19
20define max(x, y) {
21 if (x >= y) return x
22 return y
23}
24
25define min(x, y) {
26 if (x <= y) return x
27 return y
28}
29
30define sgn(c) {
31 if (x > 0) return 1
32 if (x < 0) return -1
33 return 0
34}
35
36define abs(x) {
37 return x * sgn(x)
38}
39
40define floor(x) {
41 auto s, y
42 if (x < 0) return -ceiling(-x)
43 s = scale
44 scale = 0
45 y = x / 1
46 scale = s
47 return y
48}
49
50define ceiling(x) {
51 if (x < 0) return -floor(-x)
52 if (floor(x) == x) return x
53 return 1 + floor(x)
54}
55
56/* Arithmetic */
57
58define factorial(n) {
59 auto i, res, s
60 s = scale
61 scale = 0
62 res = 1
63 for (i = 1; i <= n; i++) res *= i
64 scale = s
65 return res
66}
67
68define fact(n) {
69 return factorial(n)
70}
71
72define binomial(n, k) {
73 auto i, j, told[], tnew[], s
74 if (k < 0) return -1
75 if (k > n) return 0
76 s = scale
77 scale = 0
78 tnew[0] = 1
79 for (i = 1; i <= n; i++) {
80 for (j = 0; j <= i; j++) told[j] = tnew[j]
81 for (j = 1; j <= i; j++) tnew[j] = told[j] + told[j-1]
82 }
83 scale = s
84 return tnew[k]
85}
86
87define binom(n, k) {
88 return binomial(n, k)
89}
90
91define bin(n, k) {
92 return binomial(n, k)
93}
94
95define gcd(a, b) {
96 auto s, aux
97 s = scale
98 scale = 0
99 a /= 1
100 b /= 1
101 while (b != 0) {
102 aux = a
103 a = b
104 b = aux % b
105 }
106 scale = s
107 return a
108}
109
110define lcm(a, b) {
111 if (a == 0 || b == 0) return 0
112 return a * b / gcd(a, b)
113}
114
115define phi(n) {
116 auto i, j, f[], r, s
117 s = scale
118 scale = 0
119 j = 0
120 r = n
121 for (i = 2; i*i <= r; i++) {
122 if (n % i == 0) {
123 f[j] = i
124 j += 1
125 while (n % i == 0) n /= i
126 }
127 }
128 for (i = 0; i < j; i++) r -= r / f[i]
129 scale = s
130 return r
131}
132
133define totient(n) {
134 return phi(n)
135}
136
137/* Calculus */
138
139define exp(x) {
140 auto i, n, d, series
141 scale += 10
142 i = 0
143 n = 1
144 d = 1
145 series = 0
146 while (n/d != 0) {
147 series += n/d
148 i += 1
149 n *= x
150 d *= i
151 }
152 scale -= 10
153 return series / 1
154}
155
156define e() {
157 return exp(1)
158}
159
160/* Log: first take some square roots to make x smaller, then
161 use Newton's method to solve e^y-x=0 */
162define log(x) {
163 auto m, s, t, n, d
164 scale += 10
165 while (x > 3) {
166 m += 1
167 x = sqrt(x)
168 }
169 t = x
170 d = exp(t)
171 n = d - x
172 while (n/d != 0) {
173 t -= n/d
174 d = exp(t)
175 n = d - x
176 }
177 scale -= 10
178 return (t * 2^m) / 1
179}
180
181define ln(x) {
182 return log(x)
183}
184
185define pow(a, b) {
186 if (b != floor(b)) return (2^floor(b)) * exp(log(a)*(b-floor(b)))
187 return a ^ b
188}
189
190define trig(x, ii, in, id) {
191 auto i, n, d, series
192 scale += 10
193 i = ii
194 n = in
195 d = id
196 while (n/d != 0) {
197 series += n/d
198 i += 2
199 n *= -x*x
200 d *= i*(i-1)
201 }
202 scale -= 10
203 return series / 1
204}
205
206define sin(x) {
207 return trig(x, 1, x, 1)
208}
209
210define cos(x) {
211 return trig(x, 0, 1, 1)
212}
213
214define tan(x) {
215 return sin(x) / cos(x)
216}
217
218define sinh(x) {
219 return 0.5*(exp(x) - exp(-x))
220}
221
222define cosh(x) {
223 return 0.5*(exp(x) + exp(-x))
224}
225
226define tanh(x) {
227 return sinh(x) / cosh(x)
228}
229
230/* Atan: approximate integral of 1/(1+x^2) */
231define atan(x) {
232 auto i, n, f1, f2, a, res, s
233 s = scale
234 scale = 10
235 n = 10^4
236 res = 0
237 for (i = 0; i < n; i++) {
238 f1 = 1 + (x*i/n)^2
239 f2 = 1 + (x*(i+1)/n)^2
240 a = (f1 + f2) / (2 * f1 * f2)
241 res += a * x / n
242 }
243 scale = s
244 return res/1
245}
246
247define pi() {
248 return 4 * atan(1)
249}
250
251define atan2(y, x) {
252 if (x > 0) return atan(y/x)
253 if (x < 0 && y >= 0) return atan(y/x) + pi()
254 if (x < 0 && y < 0) return atan(y/x) - pi()
255 if (x == 0 && y > 0) return pi() / 2
256 return -pi() / 2
257}
258
259define asin(x) {
260 return atan2(x, sqrt((1+x)*(1-x)))
261}
262
263define acos(x) {
264 return atan2(sqrt((1+x)*(1-x)), x)
265}
266
267define atanh(x) {
268 return 0.5 * log((1+x)/(1-x))
269}
270
271define asinh(x) {
272 return log(x + sqrt(x^2 + 1))
273}
274
275define acosh(x) {
276 return log(x + sqrt(x^2 - 1))
277}

Generated with cgit - Back to sebastiano.tronto.net