xref: /csrg-svn/lib/libm/common/tan.c (revision 61282)
134127Sbostic /*
2*61282Sbostic  * Copyright (c) 1987, 1993
3*61282Sbostic  *	The Regents of the University of California.  All rights reserved.
434127Sbostic  *
542653Sbostic  * %sccs.include.redist.c%
631930Szliu  */
731930Szliu 
831930Szliu #ifndef lint
9*61282Sbostic static char sccsid[] = "@(#)tan.c	8.1 (Berkeley) 06/04/93";
1034127Sbostic #endif /* not lint */
1131930Szliu 
1231930Szliu #include "trig.h"
1331930Szliu double
tan(x)1431930Szliu tan(x)
1531930Szliu double x;
1631930Szliu {
1731930Szliu 	double a,z,ss,cc,c;
1831930Szliu 	int k;
1931930Szliu 
2031930Szliu 	if(!finite(x))		/* tan(NaN) and tan(INF) must be NaN */
2131930Szliu 		return x-x;
2231930Szliu 	x = drem(x,PI);			/* reduce x into [-PI/2, PI/2] */
2331930Szliu 	a = copysign(x,one);		/* ... = abs(x) */
2431930Szliu 	if (a >= PIo4) {
2531930Szliu 		k = 1;
2631930Szliu 		x = copysign(PIo2-a,x);
2731930Szliu 	}
2831930Szliu 	else {
2931930Szliu 		k = 0;
3031930Szliu 		if (a < small) {
3131930Szliu 			big+a;
3231930Szliu 			return x;
3331930Szliu 		}
3431930Szliu 	}
3531930Szliu 	z = x*x;
3631930Szliu 	cc = cos__C(z);
3731930Szliu 	ss = sin__S(z);
3831930Szliu 	z *= half;			/* Next get c = cos(x) accurately */
3931930Szliu 	c = (z >= thresh ? half-((z-half)-cc) : one-(z-cc));
4031930Szliu 	if (k == 0)
4131930Szliu 		return x+(x*(z-(cc-ss)))/c;	/* ... sin/cos */
4231930Szliu #ifdef national
4331930Szliu 	else if (x == zero)
4431930Szliu 		return copysign(fmax,x);	/* no inf on 32k */
4531930Szliu #endif	/* national */
4631930Szliu 	else
4731930Szliu 		return c/(x+x*ss);		/* ... cos/sin */
4831930Szliu }
49