1*24587Szliu /* 2*24587Szliu * Copyright (c) 1985 Regents of the University of California. 3*24587Szliu * 4*24587Szliu * Use and reproduction of this software are granted in accordance with 5*24587Szliu * the terms and conditions specified in the Berkeley Software License 6*24587Szliu * Agreement (in particular, this entails acknowledgement of the programs' 7*24587Szliu * source, and inclusion of this notice) with the additional understanding 8*24587Szliu * that all recipients should regard themselves as participants in an 9*24587Szliu * ongoing research project and hence should feel obligated to report 10*24587Szliu * their experiences (good or bad) with these elementary function codes, 11*24587Szliu * using "sendbug 4bsd-bugs@BERKELEY", to the authors. 12*24587Szliu */ 13*24587Szliu 14*24587Szliu #ifndef lint 15*24587Szliu static char sccsid[] = "@(#)asincos.c 1.1 (ELEFUNT) 09/06/85"; 16*24587Szliu #endif not lint 17*24587Szliu 18*24587Szliu /* ASIN(X) 19*24587Szliu * RETURNS ARC SINE OF X 20*24587Szliu * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) 21*24587Szliu * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. 22*24587Szliu * 23*24587Szliu * Required system supported functions: 24*24587Szliu * copysign(x,y) 25*24587Szliu * sqrt(x) 26*24587Szliu * 27*24587Szliu * Required kernel function: 28*24587Szliu * atan2(y,x) 29*24587Szliu * 30*24587Szliu * Method : 31*24587Szliu * asin(x) = atan2(x,sqrt(1-x*x)); for better accuracy, 1-x*x is 32*24587Szliu * computed as follows 33*24587Szliu * 1-x*x if x < 0.5, 34*24587Szliu * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5. 35*24587Szliu * 36*24587Szliu * Special cases: 37*24587Szliu * if x is NaN, return x itself; 38*24587Szliu * if |x|>1, return NaN. 39*24587Szliu * 40*24587Szliu * Accuracy: 41*24587Szliu * 1) If atan2() uses machine PI, then 42*24587Szliu * 43*24587Szliu * asin(x) returns (PI/pi) * (the exact arc sine of x) nearly rounded; 44*24587Szliu * and PI is the exact pi rounded to machine precision (see atan2 for 45*24587Szliu * details): 46*24587Szliu * 47*24587Szliu * in decimal: 48*24587Szliu * pi = 3.141592653589793 23846264338327 ..... 49*24587Szliu * 53 bits PI = 3.141592653589793 115997963 ..... , 50*24587Szliu * 56 bits PI = 3.141592653589793 227020265 ..... , 51*24587Szliu * 52*24587Szliu * in hexadecimal: 53*24587Szliu * pi = 3.243F6A8885A308D313198A2E.... 54*24587Szliu * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps 55*24587Szliu * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps 56*24587Szliu * 57*24587Szliu * In a test run with more than 200,000 random arguments on a VAX, the 58*24587Szliu * maximum observed error in ulps (units in the last place) was 59*24587Szliu * 2.06 ulps. (comparing against (PI/pi)*(exact asin(x))); 60*24587Szliu * 61*24587Szliu * 2) If atan2() uses true pi, then 62*24587Szliu * 63*24587Szliu * asin(x) returns the exact asin(x) with error below about 2 ulps. 64*24587Szliu * 65*24587Szliu * In a test run with more than 1,024,000 random arguments on a VAX, the 66*24587Szliu * maximum observed error in ulps (units in the last place) was 67*24587Szliu * 1.99 ulps. 68*24587Szliu */ 69*24587Szliu 70*24587Szliu double asin(x) 71*24587Szliu double x; 72*24587Szliu { 73*24587Szliu double s,t,copysign(),atan2(),sqrt(),one=1.0; 74*24587Szliu #ifndef VAX 75*24587Szliu if(x!=x) return(x); /* x is NaN */ 76*24587Szliu #endif 77*24587Szliu s=copysign(x,one); 78*24587Szliu if(s <= 0.5) 79*24587Szliu return(atan2(x,sqrt(one-x*x))); 80*24587Szliu else 81*24587Szliu { t=one-s; s=t+t; return(atan2(x,sqrt(s-t*t))); } 82*24587Szliu 83*24587Szliu } 84*24587Szliu 85*24587Szliu /* ACOS(X) 86*24587Szliu * RETURNS ARC COS OF X 87*24587Szliu * DOUBLE PRECISION (IEEE DOUBLE 53 bits, VAX D FORMAT 56 bits) 88*24587Szliu * CODED IN C BY K.C. NG, 4/16/85, REVISED ON 6/10/85. 89*24587Szliu * 90*24587Szliu * Required system supported functions: 91*24587Szliu * copysign(x,y) 92*24587Szliu * sqrt(x) 93*24587Szliu * 94*24587Szliu * Required kernel function: 95*24587Szliu * atan2(y,x) 96*24587Szliu * 97*24587Szliu * Method : 98*24587Szliu * ________ 99*24587Szliu * / 1 - x 100*24587Szliu * acos(x) = 2*atan2( / -------- , 1 ) . 101*24587Szliu * \/ 1 + x 102*24587Szliu * 103*24587Szliu * Special cases: 104*24587Szliu * if x is NaN, return x itself; 105*24587Szliu * if |x|>1, return NaN. 106*24587Szliu * 107*24587Szliu * Accuracy: 108*24587Szliu * 1) If atan2() uses machine PI, then 109*24587Szliu * 110*24587Szliu * acos(x) returns (PI/pi) * (the exact arc cosine of x) nearly rounded; 111*24587Szliu * and PI is the exact pi rounded to machine precision (see atan2 for 112*24587Szliu * details): 113*24587Szliu * 114*24587Szliu * in decimal: 115*24587Szliu * pi = 3.141592653589793 23846264338327 ..... 116*24587Szliu * 53 bits PI = 3.141592653589793 115997963 ..... , 117*24587Szliu * 56 bits PI = 3.141592653589793 227020265 ..... , 118*24587Szliu * 119*24587Szliu * in hexadecimal: 120*24587Szliu * pi = 3.243F6A8885A308D313198A2E.... 121*24587Szliu * 53 bits PI = 3.243F6A8885A30 = 2 * 1.921FB54442D18 error=.276ulps 122*24587Szliu * 56 bits PI = 3.243F6A8885A308 = 4 * .C90FDAA22168C2 error=.206ulps 123*24587Szliu * 124*24587Szliu * In a test run with more than 200,000 random arguments on a VAX, the 125*24587Szliu * maximum observed error in ulps (units in the last place) was 126*24587Szliu * 2.07 ulps. (comparing against (PI/pi)*(exact acos(x))); 127*24587Szliu * 128*24587Szliu * 2) If atan2() uses true pi, then 129*24587Szliu * 130*24587Szliu * acos(x) returns the exact acos(x) with error below about 2 ulps. 131*24587Szliu * 132*24587Szliu * In a test run with more than 1,024,000 random arguments on a VAX, the 133*24587Szliu * maximum observed error in ulps (units in the last place) was 134*24587Szliu * 2.15 ulps. 135*24587Szliu */ 136*24587Szliu 137*24587Szliu double acos(x) 138*24587Szliu double x; 139*24587Szliu { 140*24587Szliu double t,copysign(),atan2(),sqrt(),one=1.0; 141*24587Szliu #ifndef VAX 142*24587Szliu if(x!=x) return(x); 143*24587Szliu #endif 144*24587Szliu if( x != -1.0) 145*24587Szliu t=atan2(sqrt((one-x)/(one+x)),one); 146*24587Szliu else 147*24587Szliu t=atan2(one,0.0); /* t = PI/2 */ 148*24587Szliu return(t+t); 149*24587Szliu } 150