1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| double PI_4 = 0.78539816339744830675;
double PI_2 = 1.5707963267948966135;
double sq2p1 = 2.414213562373095048802;
double sq2m1 = 0.414213562373095048802;
double p4 = 16.1536412982230228262;
double p3 = 268.42548195503973794141;
double p2 = 1153.0293515404850115428136;
double p1 = 1780.40631643319697105464587;
double p0 = 896.78597403663861959987488;
double q4 = 58.95697050844462222791;
double q3 = 536.265374031215315104235;
double q2 = 1666.7838148816337184521798;
double q1 = 2079.33497444540981287275926;
double q0 = 896.78597403663861962481162;
// atan near 0
double atan_near0(double x) {
double x2,result;
x2 = x*x;
double P = ( ( ( (p4*x2 + p3)*x2 + p2) *x2 + p1) *x2 + p0);
double Q = ( ( ( ( (x2 + q4)*x2 + q3) *x2 + q2)*x2 + q1) *x2 + q0);
result = x*(P/Q);
return result;
}
// atan in range [0,+inf]
double atan_positive(double x) {
if(x < sq2m1)
return atan_near0(x);
else if(x > sq2p1)
return PI_2 - atan_near0(1/x);
else
return PI_4 + atan_near0((x-1)/(x+1));
}
// atan in range [-inf,+inf]
double atan(double x) {
if (x<0)
return -atan_positive(-x);
else
return atan_positive(x);
} |