4.3BSD-Tahoe/usr/src/cci/libM/sind.c

Compare this file to the similar file:
Show the results in this format:

/*	@(#)sin.c	4.1/4.2 	10/31/84 CCI-CPG  */


/*
 * Double-precision floating point sin/cos function.
 * Calls modf.
 * Pn coefficients are #3345 from Hart & etc.(18.79D).
 *
 * New version by Les Powers (3/26/85).
 */


static double twoopi	= 0.63661977236758134308;
static double piotwo	= 3.14159265358979323846264338327950288419716939937511/2.;
static double piotwols	= .572118872610983179676266255859012e-17;
static double piofour	= 3.14159265358979323846264338327950288419716939937511/4.;
static double threepio4	= 3.14159265358979323846264338327950288419716939937511*.75;


static double p0	=  .15707963267948966188272e1;
static double p1	= -.64596409750624619108547e0;
static double p2	=  .7969262624616543562977e-1;
static double p3	= -.468175413530264260121e-2;
static double p4	=  .1604411847068220716e-3;
static double p5	= -.359884300720869272e-5;
static double p6	=  .5692134872719023e-7;
static double p7	= -.66843217206396e-9;
static double p8	=  .587061098171e-11;

/*
 * Sn coefficients are #3043 from Hart & etc.(17.48D).
 * Cn coefficients are #3824 from Hart & etc.(19.45D).
 * The coefficients are multiplied by the appropriate power
 * of 4/pi using binary calculator with 40 digit arithmetic.
 * The following statements in comments indicate the
 * operations originally used to generate the coefficients.
 *
 * #define FP (4/3.14159265358979323846264338327950288419716939937511)
 * #define FS FP*FP
 *
 * static double s0	=  .785398163397448307014e0*FP;
 * static double s1	= -.80745512188280530192e-1*FP*FS;
 * static double s2	=  .2490394570188736117e-2*FP*FS*FS;
 * static double s3	= -.36576204158455695e-4*FP*FS*FS*FS;
 * static double s4	=  .313361621661904e-6*FP*FS*FS*FS*FS;
 * static double s5	= -.1757149292755e-8*FP*FS*FS*FS*FS*FS;
 * static double s6	=  .6877100349e-11*FP*FS*FS*FS*FS*FS*FS;
 *
 * static double c0	=  .99999999999999999996415e0;
 * static double c1	= -.30842513753404245242414e0*FS;
 * static double c2	=  .1585434424381541089754e-1*FS*FS;
 * static double c3	= -.32599188692668755044e-3*FS*FS*FS;
 * static double c4	=  .359086044588581953e-5*FS*FS*FS*FS;
 * static double c5	= -.2461136382637005e-7*FS*FS*FS*FS*FS;
 * static double c6	=  .11500497024263e-9*FS*FS*FS*FS*FS*FS;
 * static double c7	= -.38577620372e-12*FS*FS*FS*FS*FS*FS*FS;
 */

static double s0 = .9999999999999999966874625291130031549274;
static double s1 = -.1666666666666661475150697663344387409506;
static double s2 = .0083333333333200019685518812023464185712;
static double s3 = -.0001984126982840175394529286095367983768;
static double s4 = .0000027557313298885682473645051747116530;
static double s5 = -.0000000250507058263681718011320436448899;
static double s6 = .0000000001589413523004632819499530093565;

static double c0 = 0.99999999999999999996415;
static double c1 = -.4999999999999999928435829208978050890709;
static double c2 = .0416666666666664302573692446884954307432;
static double c3 = -.0013888888888858960434395194724966502603;
static double c4 = .0000248015872828994630247806807330993132;
static double c5 = -.0000002755731286569608222434728722627332;
static double c6 = .0000000020875555145677882874779379760684;
static double c7 = -.0000000000113521232057839395845871741059;


double
cos(arg)
double arg;
{
	double sinus();
	double s;
	union {
	  double d;
	  unsigned i;
	} u;
	if ( arg < 0 )
	  arg = -arg;
	u.d = arg;
	if ( u.i < 0x40490fdb ) {		/* arg < pi * 1/4 */
	  s = arg * arg;
	  return(c0+s*(c1+s*(c2+s*(c3+s*(c4+s*(c5+s*(c6+s*c7)))))));
	}
	if ( u.i < 0x4116cbe3 ) {		/* arg < pi * 3/4 */
	  arg = (piotwo - arg)+piotwols;
	  s = arg * arg;
	  return(arg*(s0+s*(s1+s*(s2+s*(s3+s*(s4+s*(s5+s*s6)))))));
	}
	return(sinus(arg, 1));
}

double
sin(arg)
double arg;
{
	double sinus();
	double s;
	union {
	  double d;
	  unsigned i;
	} u;
	if ( arg < 0 )
	  return( -sin(-arg) );
	u.d = arg;
	if ( u.i < 0x40490fdb ) {		/* arg < pi * 1/4 */
	  s = arg * arg;
	  return(arg*(s0+s*(s1+s*(s2+s*(s3+s*(s4+s*(s5+s*s6)))))));
	}
	if ( u.i < 0x4116cbe3 ) {		/* arg < pi * 3/4 */
	  arg = (piotwo - arg)+piotwols;
	  s = arg * arg;
	  return(c0+s*(c1+s*(c2+s*(c3+s*(c4+s*(c5+s*(c6+s*c7)))))));
	}
	return(sinus(arg, 0));
}

static double
sinus(arg, quad)
double arg;
int quad;
{
	double modf();
	double e, f;
	double ysq;
	double x,y;
	int k;
	double temp1, temp2;

	x = arg;
	if(x < 0) {
		x = -x;
		quad = quad + 2;
	}
	x = x * twoopi; /*underflow?*/
	if (x > 32764){
		y = modf(x,&e);
		e = e + quad;
		modf(0.25 * e,&f);
		quad = e - 4 * f;
	}else{
		k = x;
		y = x - k;
		quad = (quad + k) & 03;
	}
	if (quad & 01)
		y = 1-y;
	if (quad > 1)
		y = -y;

	ysq = y * y;
	temp1 = ((((((((p8*ysq+p7)*ysq+p6)*ysq+p5)*ysq+p4)*ysq+
		p3)*ysq+p2)*ysq+p1)*ysq+p0);
	return(temp1 * y);
}