1 /* 2 * Copyright (c) 1987 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 * 12 * All recipients should regard themselves as participants in an ongoing 13 * research project and hence should feel obligated to report their 14 * experiences (good or bad) with these elementary function codes, using 15 * the sendbug(8) program, to the authors. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)tan.c 5.2 (Berkeley) 04/29/88"; 20 #endif /* not lint */ 21 22 #include "trig.h" 23 double 24 tan(x) 25 double x; 26 { 27 double a,z,ss,cc,c; 28 int k; 29 30 if(!finite(x)) /* tan(NaN) and tan(INF) must be NaN */ 31 return x-x; 32 x = drem(x,PI); /* reduce x into [-PI/2, PI/2] */ 33 a = copysign(x,one); /* ... = abs(x) */ 34 if (a >= PIo4) { 35 k = 1; 36 x = copysign(PIo2-a,x); 37 } 38 else { 39 k = 0; 40 if (a < small) { 41 big+a; 42 return x; 43 } 44 } 45 z = x*x; 46 cc = cos__C(z); 47 ss = sin__S(z); 48 z *= half; /* Next get c = cos(x) accurately */ 49 c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc)); 50 if (k == 0) 51 return x+(x*(z-(cc-ss)))/c; /* ... sin/cos */ 52 #ifdef national 53 else if (x == zero) 54 return copysign(fmax,x); /* no inf on 32k */ 55 #endif /* national */ 56 else 57 return c/(x+x*ss); /* ... cos/sin */ 58 } 59