1 /* 2 floating point tangent 3 4 A series is used after range reduction. 5 Coefficients are #4285 from Hart & Cheney. (19.74D) 6 */ 7 8 #include <u.h> 9 #include <libc.h> 10 11 static double p0 = -0.1306820264754825668269611177e+5; 12 static double p1 = 0.1055970901714953193602353981e+4; 13 static double p2 = -0.1550685653483266376941705728e+2; 14 static double p3 = 0.3422554387241003435328470489e-1; 15 static double p4 = 0.3386638642677172096076369e-4; 16 static double q0 = -0.1663895238947119001851464661e+5; 17 static double q1 = 0.4765751362916483698926655581e+4; 18 static double q2 = -0.1555033164031709966900124574e+3; 19 20 double tan(double arg)21tan(double arg) 22 { 23 double temp, e, x, xsq; 24 int flag, sign, i; 25 26 flag = 0; 27 sign = 0; 28 if(arg < 0){ 29 arg = -arg; 30 sign++; 31 } 32 arg = 2*arg/PIO2; /* overflow? */ 33 x = modf(arg, &e); 34 i = e; 35 switch(i%4) { 36 case 1: 37 x = 1 - x; 38 flag = 1; 39 break; 40 41 case 2: 42 sign = !sign; 43 flag = 1; 44 break; 45 46 case 3: 47 x = 1 - x; 48 sign = !sign; 49 break; 50 51 case 0: 52 break; 53 } 54 55 xsq = x*x; 56 temp = ((((p4*xsq+p3)*xsq+p2)*xsq+p1)*xsq+p0)*x; 57 temp = temp/(((xsq+q2)*xsq+q1)*xsq+q0); 58 59 if(flag) { 60 if(temp == 0) 61 return NaN(); 62 temp = 1/temp; 63 } 64 if(sign) 65 temp = -temp; 66 return temp; 67 } 68