xref: /csrg-svn/lib/libm/common/sincos.c (revision 34127)
1*34127Sbostic /*
231931Szliu  * Copyright (c) 1987 Regents of the University of California.
3*34127Sbostic  * All rights reserved.
4*34127Sbostic  *
5*34127Sbostic  * Redistribution and use in source and binary forms are permitted
6*34127Sbostic  * provided that this notice is preserved and that due credit is given
7*34127Sbostic  * to the University of California at Berkeley. The name of the University
8*34127Sbostic  * may not be used to endorse or promote products derived from this
9*34127Sbostic  * software without specific prior written permission. This software
10*34127Sbostic  * is provided ``as is'' without express or implied warranty.
11*34127Sbostic  *
12*34127Sbostic  * All recipients should regard themselves as participants in an ongoing
13*34127Sbostic  * research project and hence should feel obligated to report their
14*34127Sbostic  * experiences (good or bad) with these elementary function codes, using
15*34127Sbostic  * the sendbug(8) program, to the authors.
1631931Szliu  */
1731931Szliu 
1831931Szliu #ifndef lint
19*34127Sbostic static char sccsid[] = "@(#)sincos.c	5.2 (Berkeley) 04/29/88";
20*34127Sbostic #endif /* not lint */
2131931Szliu 
2231931Szliu #include "trig.h"
2331931Szliu double
2431931Szliu sin(x)
2531931Szliu double x;
2631931Szliu {
2731931Szliu 	double a,c,z;
2831931Szliu 
2931931Szliu         if(!finite(x))		/* sin(NaN) and sin(INF) must be NaN */
3031931Szliu 		return x-x;
3131931Szliu 	x=drem(x,PI2);		/* reduce x into [-PI,PI] */
3231931Szliu 	a=copysign(x,one);
3331931Szliu 	if (a >= PIo4) {
3431931Szliu 		if(a >= PI3o4)		/* ... in [3PI/4,PI] */
3531931Szliu 			x = copysign((a = PI-a),x);
3631931Szliu 		else {			/* ... in [PI/4,3PI/4]  */
3731931Szliu 			a = PIo2-a;		/* rtn. sign(x)*C(PI/2-|x|) */
3831931Szliu 			z = a*a;
3931931Szliu 			c = cos__C(z);
4031931Szliu 			z *= half;
4131931Szliu 			a = (z >= thresh ? half-((z-half)-c) : one-(z-c));
4231931Szliu 			return copysign(a,x);
4331931Szliu 		}
4431931Szliu 	}
4531931Szliu 
4631931Szliu 	if (a < small) {		/* rtn. S(x) */
4731931Szliu 		big+a;
4831931Szliu 		return x;
4931931Szliu 	}
5031931Szliu 	return x+x*sin__S(x*x);
5131931Szliu }
5231931Szliu 
5331931Szliu double
5431931Szliu cos(x)
5531931Szliu double x;
5631931Szliu {
5731931Szliu 	double a,c,z,s = 1.0;
5831931Szliu 
5931931Szliu 	if(!finite(x))		/* cos(NaN) and cos(INF) must be NaN */
6031931Szliu 		return x-x;
6131931Szliu 	x=drem(x,PI2);		/* reduce x into [-PI,PI] */
6231931Szliu 	a=copysign(x,one);
6331931Szliu 	if (a >= PIo4) {
6431931Szliu 		if (a >= PI3o4) {	/* ... in [3PI/4,PI] */
6531931Szliu 			a = PI-a;
6631931Szliu 			s = negone;
6731931Szliu 		}
6831931Szliu 		else {			/* ... in [PI/4,3PI/4] */
6931931Szliu 			a = PIo2-a;
7031931Szliu 			return a+a*sin__S(a*a);	/* rtn. S(PI/2-|x|) */
7131931Szliu 		}
7231931Szliu 	}
7331931Szliu 	if (a < small) {
7431931Szliu 		big+a;
7531931Szliu 		return s;		/* rtn. s*C(a) */
7631931Szliu 	}
7731931Szliu 	z = a*a;
7831931Szliu 	c = cos__C(z);
7931931Szliu 	z *= half;
8031931Szliu 	a = (z >= thresh ? half-((z-half)-c) : one-(z-c));
8131931Szliu 	return copysign(a,s);
8231931Szliu }
83