1 /* libmath.b for bc for minix. */
3 /* This file is part of bc written for MINIX.
4 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License , or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 You may contact the author by:
21 e-mail: phil@cs.wwu.edu
22 us-mail: Philip A. Nelson
23 Computer Science Department, 9062
24 Western Washington University
25 Bellingham, WA 98226-9062
27 *************************************************************************/
32 /* Uses the fact that e^x = (e^(x/2))^2
33 When x is small enough, we use the series:
34 e^x = 1 + x + x^2/2! + x^3/3! + ...
38 auto a, d, e, f, i, m, v, z
40 /* Check the sign of x. */
48 scale = 4 + z + .44*x;
54 /* Initialize the variables. */
60 e = (a *= x) / (d *= i)
62 if (f>0) while (f--) v = v*v;
71 /* Natural log. Uses the fact that ln(x^2) = 2*ln(x)
73 ln(x) = 2(a+a^3/3+a^5/5+...) where a=(x-1)/(x+1)
77 auto e, f, i, m, n, v, z
79 /* return something for the special case. */
80 if (x <= 0) return (1 - 10^scale)
82 /* Precondition x to make .5 < x < 2.0. */
87 while (x >= 2) { /* for large numbers */
91 while (x <= .5) { /* for small numbers */
96 /* Set up the loop. */
100 /* Sum the series. */
112 /* Sin(x) uses the standard series:
113 sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... */
116 auto e, i, m, n, s, v, z
118 /* precondition x. */
139 if (m) return (-v/1);
146 /* Cosine : cos(x) = sin(x+pi/2) */
155 /* Arctan: Using the formula:
156 atan(x) = atan(c) + atan((x-c)/(1+xc)) for a small c (.2 here)
157 For under .2, use the series:
158 atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... */
161 auto a, e, f, i, m, n, s, v, z
163 /* Special case and for fast answers */
165 if (scale <= 25) return (.7853981633974483096156608/1)
166 if (scale <= 40) return (.7853981633974483096156608458198757210492/1)
168 return (.785398163397448309615660845819875721049292349843776455243736/1)
171 if (scale <= 25) return (.1973955598498807583700497/1)
172 if (scale <= 40) return (.1973955598498807583700497651947902934475/1)
174 return (.197395559849880758370049765194790293447585103787852101517688/1)
183 /* Save the scale. */
186 /* Note: a and f are known to be zero due to being auto vars. */
187 /* Calculate atan of a known number. */
193 /* Precondition x. */
197 x = (x-.2) / (1+x*.2);
200 /* Initialize the series. */
204 /* Calculate the series. */
209 if (m) return ((f*a+v)/-1);
217 /* Bessel function of integer order. Uses the following:
218 j(-n,x) = (-1)^n*j(n,x)
219 j(n,x) = x^n/(2^n*n!) * (1 - x^2/(2^2*1!*(n+1)) + x^4/(2^4*2!*(n+1)*(n+2))
220 - x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... )
223 auto a, d, e, f, i, m, s, v, z
225 /* Make n an integer and check for negative n. */
234 /* Compute the factor of x^n/(2^n*n!) */
236 for (i=2; i<=n; i++) f = f*i;
240 /* Initialize the loop .*/
247 e = e * s / i / (n+i);
250 if (m) return (-f*v/1);