1b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 2b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project/* @(#)e_atan2.c 1.3 95/01/18 */ 3b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project/* 4b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ==================================================== 5b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 6b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 7b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Developed at SunSoft, a Sun Microsystems, Inc. business. 8b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Permission to use, copy, modify, and distribute this 9b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * software is freely granted, provided that this notice 10b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * is preserved. 11b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ==================================================== 12b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 13b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project */ 14b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 15b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project/* __ieee754_atan2(y,x) 16b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Method : 17b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 1. Reduce y to positive by ieee_atan2(y,x)=-ieee_atan2(-y,x). 18b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 2. Reduce x to positive by (if x and y are unexceptional): 19b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ARG (x+iy) = arctan(y/x) ... if x > 0, 20b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, 21b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 22b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Special cases: 23b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 24b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2((anything), NaN ) is NaN; 25b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(NAN , (anything) ) is NaN; 26b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-0, +(anything but NaN)) is +-0 ; 27b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-0, -(anything but NaN)) is +-pi ; 28b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; 29b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; 30b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; 31b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-INF,+INF ) is +-pi/4 ; 32b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-INF,-INF ) is +-3pi/4; 33b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; 34b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * 35b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * Constants: 36b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * The hexadecimal values are the intended ones for the following 37b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * constants. The decimal values may be used, provided that the 38b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * compiler will convert from decimal to binary accurately enough 39b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project * to produce the hexadecimal values shown. 40b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project */ 41b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 42b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#include "fdlibm.h" 43b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 44b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#ifdef __STDC__ 45b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectstatic const double 46b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#else 47b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectstatic double 48b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#endif 49b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projecttiny = 1.0e-300, 50b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectzero = 0.0, 51b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectpi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ 52b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectpi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ 53b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectpi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ 54b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Projectpi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ 55b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 56b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#ifdef __STDC__ 57b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project double __ieee754_atan2(double y, double x) 58b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#else 59b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project double __ieee754_atan2(y,x) 60b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project double y,x; 61b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project#endif 62b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project{ 63b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project double z; 64b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project int k,m,hx,hy,ix,iy; 65b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project unsigned lx,ly; 66b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 67b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project hx = __HI(x); ix = hx&0x7fffffff; 68b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project lx = __LO(x); 69b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project hy = __HI(y); iy = hy&0x7fffffff; 70b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project ly = __LO(y); 71b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if(((ix|((lx|-lx)>>31))>0x7ff00000)|| 72b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ 73b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project return x+y; 74b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if((hx-0x3ff00000|lx)==0) return ieee_atan(y); /* x=1.0 */ 75b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ 76b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 77b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project /* when y = 0 */ 78b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if((iy|ly)==0) { 79b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project switch(m) { 80b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 0: 81b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 1: return y; /* ieee_atan(+-0,+anything)=+-0 */ 82b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 2: return pi+tiny;/* ieee_atan(+0,-anything) = pi */ 83b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 3: return -pi-tiny;/* ieee_atan(-0,-anything) =-pi */ 84b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 85b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 86b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project /* when x = 0 */ 87b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; 88b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 89b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project /* when x is INF */ 90b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if(ix==0x7ff00000) { 91b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if(iy==0x7ff00000) { 92b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project switch(m) { 93b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 0: return pi_o_4+tiny;/* ieee_atan(+INF,+INF) */ 94b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 1: return -pi_o_4-tiny;/* ieee_atan(-INF,+INF) */ 95b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 2: return 3.0*pi_o_4+tiny;/*ieee_atan(+INF,-INF)*/ 96b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 3: return -3.0*pi_o_4-tiny;/*ieee_atan(-INF,-INF)*/ 97b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 98b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } else { 99b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project switch(m) { 100b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 0: return zero ; /* ieee_atan(+...,+INF) */ 101b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 1: return -zero ; /* ieee_atan(-...,+INF) */ 102b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 2: return pi+tiny ; /* ieee_atan(+...,-INF) */ 103b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 3: return -pi-tiny ; /* ieee_atan(-...,-INF) */ 104b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 105b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 106b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 107b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project /* when y is INF */ 108b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; 109b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project 110b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project /* compute y/x */ 111b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project k = (iy-ix)>>20; 112b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */ 113b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ 114b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project else z=ieee_atan(ieee_fabs(y/x)); /* safe to do y/x */ 115b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project switch (m) { 116b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 0: return z ; /* ieee_atan(+,+) */ 117b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 1: __HI(z) ^= 0x80000000; 118b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project return z ; /* ieee_atan(-,+) */ 119b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project case 2: return pi-(z-pi_lo);/* ieee_atan(+,-) */ 120b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project default: /* case 3 */ 121b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project return (z-pi_lo)-pi;/* ieee_atan(-,-) */ 122b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project } 123b07e1d9fd8d9e4e03698e0bd9bf77154c5390326The Android Open Source Project} 124