1 /* 2 * Copyright (c) 1987 Regents of the University of California. 3 * 4 * Use and reproduction of this software are granted in accordance with 5 * the terms and conditions specified in the Berkeley Software License 6 * Agreement (in particular, this entails acknowledgement of the programs' 7 * source, and inclusion of this notice) with the additional understanding 8 * that all recipients should regard themselves as participants in an 9 * ongoing research project and hence should feel obligated to report 10 * their experiences (good or bad) with these elementary function codes, 11 * using "sendbug 4bsd-bugs@BERKELEY", to the authors. 12 */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)tan.c 5.1 5.1 (ucb.elefunt) 11/30/87"; 16 #endif /* not lint */ 17 18 #include "trig.h" 19 double 20 tan(x) 21 double x; 22 { 23 double a,z,ss,cc,c; 24 int k; 25 26 if(!finite(x)) /* tan(NaN) and tan(INF) must be NaN */ 27 return x-x; 28 x = drem(x,PI); /* reduce x into [-PI/2, PI/2] */ 29 a = copysign(x,one); /* ... = abs(x) */ 30 if (a >= PIo4) { 31 k = 1; 32 x = copysign(PIo2-a,x); 33 } 34 else { 35 k = 0; 36 if (a < small) { 37 big+a; 38 return x; 39 } 40 } 41 z = x*x; 42 cc = cos__C(z); 43 ss = sin__S(z); 44 z *= half; /* Next get c = cos(x) accurately */ 45 c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc)); 46 if (k == 0) 47 return x+(x*(z-(cc-ss)))/c; /* ... sin/cos */ 48 #ifdef national 49 else if (x == zero) 50 return copysign(fmax,x); /* no inf on 32k */ 51 #endif /* national */ 52 else 53 return c/(x+x*ss); /* ... cos/sin */ 54 } 55