double atan(double x) { /* Algorithm and coefficients from: "Software manual for the elementary functions" by W.J. Cody and W. Waite, Prentice-Hall, 1980 */ static double p[] = { -0.13688768894191926929e+2, -0.20505855195861651981e+2, -0.84946240351320683534e+1, -0.83758299368150059274e+0 }; static double q[] = { 0.41066306682575781263e+2, 0.86157349597130242515e+2, 0.59578436142597344465e+2, 0.15024001160028576121e+2, 1.0 }; static double a[] = { 0.0, 0.52359877559829887307710723554658381, /* pi/6 */ M_PI_2, 1.04719755119659774615421446109316763 /* pi/3 */ }; int neg = x < 0; int n; double g; if (__IsNan(x)) { errno = EDOM; return x; } if (neg) { x = -x; } if (x > 1.0) { x = 1.0/x; n = 2; } else n = 0; if (x > 0.26794919243112270647) { /* 2-sqtr(3) */ n = n + 1; x = (((0.73205080756887729353*x-0.5)-0.5)+x)/ (1.73205080756887729353+x); } /* ??? avoid underflow ??? */ g = x * x; x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q); if (n > 1) x = -x; x += a[n]; return neg ? -x : x; }
static double asin_acos(double x, int cosfl) { int negative = x < 0; int i; double g; static double p[] = { -0.27368494524164255994e+2, 0.57208227877891731407e+2, -0.39688862997540877339e+2, 0.10152522233806463645e+2, -0.69674573447350646411e+0 }; static double q[] = { -0.16421096714498560795e+3, 0.41714430248260412556e+3, -0.38186303361750149284e+3, 0.15095270841030604719e+3, -0.23823859153670238830e+2, 1.0 }; if (__IsNan(x)) { errno = EDOM; return x; } if (negative) { x = -x; } if (x > 0.5) { i = 1; if (x > 1) { errno = EDOM; return 0; } g = 0.5 - 0.5 * x; x = - sqrt(g); x += x; } else { /* ??? avoid underflow ??? */ i = 0; g = x * x; } x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q); if (cosfl) { if (! negative) x = -x; } if ((cosfl == 0) == (i == 1)) { x = (x + M_PI_4) + M_PI_4; } else if (cosfl && negative && i == 1) { x = (x + M_PI_2) + M_PI_2; } if (! cosfl && negative) x = -x; return x; }
/****** BEGIN ************************************************************* */ float mymathAtan(float x) { static float p[] = { -0.13688768894191926929e+2, -0.20505855195861651981e+2, -0.84946240351320683534e+1, -0.83758299368150059274e+0 }; static float q[] = { 0.41066306682575781263e+2, 0.86157349597130242515e+2, 0.59578436142597344465e+2, 0.15024001160028576121e+2, 1.0 }; static float a[] = { 0.0, MATH_PI6, /* pi/6 */ MATH_PI2, /* pi/2 */ MATH_PI3 /* pi/3 */ }; int32_t neg = x < 0; int32_t n; float g; if (neg) { x = -x; } if (x > 1.0) { x = 1.0 / x; n = 2; } else n = 0; if (x > 0.26794919243112270647) { /* 2-sqtr(3) */ n = n + 1; x = (((0.73205080756887729353 * x - 0.5) - 0.5) + x) / (1.73205080756887729353 + x); } g = x * x; x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q); if (n > 1) x = -x; x += a[n]; return neg ? -x : x; }
double tan(double x) { /* Algorithm and coefficients from: "Software manual for the elementary functions" by W.J. Cody and W. Waite, Prentice-Hall, 1980 */ int negative = x < 0; int invert = 0; double y; static double p[] = { 1.0, -0.13338350006421960681e+0, 0.34248878235890589960e-2, -0.17861707342254426711e-4 }; static double q[] = { 1.0, -0.46671683339755294240e+0, 0.25663832289440112864e-1, -0.31181531907010027307e-3, 0.49819433993786512270e-6 }; if (__IsNan(x)) { errno = EDOM; return x; } if (negative) x = -x; /* ??? avoid loss of significance, error if x is too large ??? */ y = x * M_2_PI + 0.5; if (y >= DBL_MAX/M_PI_2) return 0.0; /* Use extended precision to calculate reduced argument. Here we used 12 bits of the mantissa for a1. Also split x in integer part x1 and fraction part x2. */ #define A1 1.57080078125 #define A2 -4.454455103380768678308e-6 { double x1, x2; modf(y, &y); if (modf(0.5*y, &x1)) invert = 1; x2 = modf(x, &x1); x = x1 - y * A1; x += x2; x -= y * A2; #undef A1 #undef A2 } /* ??? avoid underflow ??? */ y = x * x; x += x * y * POLYNOM2(y, p+1); y = POLYNOM4(y, q); if (negative) x = -x; return invert ? -y/x : x/y; }