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 the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * All recipients should regard themselves as participants in an ongoing 18 * research project and hence should feel obligated to report their 19 * experiences (good or bad) with these elementary function codes, using 20 * the sendbug(8) program, to the authors. 21 */ 22 23 #ifndef lint 24 static char sccsid[] = "@(#)tan.c 5.3 (Berkeley) 06/30/88"; 25 #endif /* not lint */ 26 27 #include "trig.h" 28 double 29 tan(x) 30 double x; 31 { 32 double a,z,ss,cc,c; 33 int k; 34 35 if(!finite(x)) /* tan(NaN) and tan(INF) must be NaN */ 36 return x-x; 37 x = drem(x,PI); /* reduce x into [-PI/2, PI/2] */ 38 a = copysign(x,one); /* ... = abs(x) */ 39 if (a >= PIo4) { 40 k = 1; 41 x = copysign(PIo2-a,x); 42 } 43 else { 44 k = 0; 45 if (a < small) { 46 big+a; 47 return x; 48 } 49 } 50 z = x*x; 51 cc = cos__C(z); 52 ss = sin__S(z); 53 z *= half; /* Next get c = cos(x) accurately */ 54 c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc)); 55 if (k == 0) 56 return x+(x*(z-(cc-ss)))/c; /* ... sin/cos */ 57 #ifdef national 58 else if (x == zero) 59 return copysign(fmax,x); /* no inf on 32k */ 60 #endif /* national */ 61 else 62 return c/(x+x*ss); /* ... cos/sin */ 63 } 64