/* * +++ NAME +++ * * DSIN Double precision sine * * +++ INDEX +++ * * DSIN * machine independent routines * trigonometric functions * math libraries * * +++ DESCRIPTION +++ * * Returns double precision sine of double precision * floating point argument. * * +++ USAGE +++ * * double dsin(x) * double x; * * +++ REFERENCES +++ * * Computer Approximations, J.F. Hart et al, John Wiley & Sons, * 1968, pp. 112-120. * * +++ RESTRICTIONS +++ * * The DSIN and DCOS routines are interactive in the sense that * in the process of reducing the argument to the range -PI/4 * to PI/4, each may call the other. Ultimately one or the * other uses a polynomial approximation on the reduced * argument. The DSIN approximation has a maximum relative error * of 10**(-17.59) and the DCOS approximation has a maximum * relative error of 10**(-16.18). * * These error bounds assume exact arithmetic * in the polynomial evaluation. Additional rounding and * truncation errors may occur as the argument is reduced * to the range over which the polynomial approximation * is valid, and as the polynomial is evaluated using * finite-precision arithmetic. * * +++ PROGRAMMER +++ * * Fred Fish * Goodyear Aerospace Corp, Arizona Div. * (602) 932-7000 work * (602) 894-6881 home * * +++ INTERNALS +++ * * Computes DSIN(X) from: * * (1) Reduce argument X to range -PI to PI. * * (2) If X > PI/2 then call DSIN recursively * using relation DSIN(X) = -DSIN(X - PI). * * (3) If X < -PI/2 then call DSIN recursively * using relation DSIN(X) = -DSIN(X + PI). * * (4) If X > PI/4 then call DCOS using * relation DSIN(X) = DCOS(PI/2 - X). * * (5) If X < -PI/4 then call DCOS using * relation DSIN(X) = -DCOS(PI/2 + X). * * (6) If X is small enough that polynomial * evaluation would cause underflow * then return X, since SIN(X) * approaches X as X approaches zero. * * (7) By now X has been reduced to range * -PI/4 to PI/4 and the approximation * from HART pg. 118 can be used: * * DSIN(X) = Y * ( P(Y) / Q(Y) ) * Where: * * Y = X * (4/PI) * * P(Y) = SUM [ Pj * (Y**(2*j)) ] * over j = {0,1,2,3} * * Q(Y) = SUM [ Qj * (Y**(2*j)) ] * over j = {0,1,2,3} * * P0 = 0.206643433369958582409167054e+7 * P1 = -0.18160398797407332550219213e+6 * P2 = 0.359993069496361883172836e+4 * P3 = -0.2010748329458861571949e+2 * Q0 = 0.263106591026476989637710307e+7 * Q1 = 0.3927024277464900030883986e+5 * Q2 = 0.27811919481083844087953e+3 * Q3 = 1.0000... * (coefficients from HART table #3063 pg 234) * * * **** NOTE **** The range reduction relations used in * this routine depend on the final approximation being valid * over the negative argument range in addition to the positive * argument range. The particular approximation chosen from * HART satisfies this requirement, although not explicitly * stated in the text. This may not be true of other * approximations given in the reference. * * --- */ /*)LIBRARY */ #include #include "c:pmluse.h" #include "pml.h" static double dsin_pcoeffs[] = { 0.20664343336995858240e7, -0.18160398797407332550e6, 0.35999306949636188317e4, -0.20107483294588615719e2 }; static double dsin_qcoeffs[] = { 0.26310659102647698963e7, 0.39270242774649000308e5, 0.27811919481083844087e3, 1.0 }; double dsin(x) double x; { double y, yt2, dmod(), dcos(), dpoly(); if (x < -PI || x > PI) { x = dmod(x,TWOPI); if (x > PI) { x = x - TWOPI; } else if (x < -PI) { x = x + TWOPI; } } if (x > HALFPI) { return (-(dsin(x - PI))); } else if (x < -HALFPI) { return (-(dsin(x + PI))); } else if (x > FOURTHPI) { return (dcos(HALFPI - x)); } else if (x < -FOURTHPI) { return (-(dcos(HALFPI + x))); } else if (x < X6_UNDERFLOWS && x > -X6_UNDERFLOWS) { return (x); } else { y = x / FOURTHPI; yt2 = y * y; return ( y * (dpoly(3,dsin_pcoeffs,yt2) / dpoly(3,dsin_qcoeffs,yt2))); } }