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