SDL  2.0
e_atan2.c
Go to the documentation of this file.
1 /*
2  * ====================================================
3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4  *
5  * Developed at SunPro, a Sun Microsystems, Inc. business.
6  * Permission to use, copy, modify, and distribute this
7  * software is freely granted, provided that this notice
8  * is preserved.
9  * ====================================================
10  */
11 
12 /* __ieee754_atan2(y,x)
13  * Method :
14  * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
15  * 2. Reduce x to positive by (if x and y are unexceptional):
16  * ARG (x+iy) = arctan(y/x) ... if x > 0,
17  * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
18  *
19  * Special cases:
20  *
21  * ATAN2((anything), NaN ) is NaN;
22  * ATAN2(NAN , (anything) ) is NaN;
23  * ATAN2(+-0, +(anything but NaN)) is +-0 ;
24  * ATAN2(+-0, -(anything but NaN)) is +-pi ;
25  * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
26  * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
27  * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
28  * ATAN2(+-INF,+INF ) is +-pi/4 ;
29  * ATAN2(+-INF,-INF ) is +-3pi/4;
30  * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
31  *
32  * Constants:
33  * The hexadecimal values are the intended ones for the following
34  * constants. The decimal values may be used, provided that the
35  * compiler will convert from decimal to binary accurately enough
36  * to produce the hexadecimal values shown.
37  */
38 
39 #include "math_libm.h"
40 #include "math_private.h"
41 
42 static const double
43 tiny = 1.0e-300,
44 zero = 0.0,
45 pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
46 pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
47 pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
48 pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
49 
50 double attribute_hidden __ieee754_atan2(double y, double x)
51 {
52  double z;
53  int32_t k,m,hx,hy,ix,iy;
54  u_int32_t lx,ly;
55 
56  EXTRACT_WORDS(hx,lx,x);
57  ix = hx&0x7fffffff;
58  EXTRACT_WORDS(hy,ly,y);
59  iy = hy&0x7fffffff;
60  if(((ix|((lx|-(int32_t)lx)>>31))>0x7ff00000)||
61  ((iy|((ly|-(int32_t)ly)>>31))>0x7ff00000)) /* x or y is NaN */
62  return x+y;
63  if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */
64  m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
65 
66  /* when y = 0 */
67  if((iy|ly)==0) {
68  switch(m) {
69  case 0:
70  case 1: return y; /* atan(+-0,+anything)=+-0 */
71  case 2: return pi+tiny;/* atan(+0,-anything) = pi */
72  case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
73  }
74  }
75  /* when x = 0 */
76  if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
77 
78  /* when x is INF */
79  if(ix==0x7ff00000) {
80  if(iy==0x7ff00000) {
81  switch(m) {
82  case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
83  case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
84  case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
85  case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
86  }
87  } else {
88  switch(m) {
89  case 0: return zero ; /* atan(+...,+INF) */
90  case 1: return -zero ; /* atan(-...,+INF) */
91  case 2: return pi+tiny ; /* atan(+...,-INF) */
92  case 3: return -pi-tiny ; /* atan(-...,-INF) */
93  }
94  }
95  }
96  /* when y is INF */
97  if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
98 
99  /* compute y/x */
100  k = (iy-ix)>>20;
101  if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
102  else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
103  else z=atan(fabs(y/x)); /* safe to do y/x */
104  switch (m) {
105  case 0: return z ; /* atan(+,+) */
106  case 1: {
107  u_int32_t zh;
108  GET_HIGH_WORD(zh,z);
109  SET_HIGH_WORD(z,zh ^ 0x80000000);
110  }
111  return z ; /* atan(-,+) */
112  case 2: return pi-(z-pi_lo);/* atan(+,-) */
113  default: /* case 3 */
114  return (z-pi_lo)-pi;/* atan(-,-) */
115  }
116 }
117 
118 /*
119  * wrapper atan2(y,x)
120  */
121 #ifndef _IEEE_LIBM
122 double atan2(double y, double x)
123 {
124  double z = __ieee754_atan2(y, x);
125  if (_LIB_VERSION == _IEEE_ || isnan(x) || isnan(y))
126  return z;
127  if (x == 0.0 && y == 0.0)
128  return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */
129  return z;
130 }
131 #else
133 #endif
134 libm_hidden_def(atan2)
pi_o_2
static const double pi_o_2
Definition: e_atan2.c:46
fabs
double fabs(double x)
Definition: s_fabs.c:22
math_private.h
pi_o_4
static const double pi_o_4
Definition: e_atan2.c:45
attribute_hidden
#define attribute_hidden
Definition: math_private.h:25
pi
static const double pi
Definition: e_atan2.c:47
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:407
__ieee754_atan2
double attribute_hidden __ieee754_atan2(double y, double x)
Definition: e_atan2.c:50
EXTRACT_WORDS
#define EXTRACT_WORDS(ix0, ix1, d)
Definition: math_private.h:99
libm_hidden_def
libm_hidden_def(scalbln)
Definition: s_scalbn.c:66
SET_HIGH_WORD
#define SET_HIGH_WORD(d, v)
Definition: math_private.h:137
strong_alias
#define strong_alias(x, y)
Definition: math_private.h:28
math_libm.h
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
int32_t
signed int int32_t
Definition: SDL_config_windows.h:62
u_int32_t
unsigned int u_int32_t
Definition: math_private.h:31
tiny
static const double tiny
Definition: e_atan2.c:43
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
m
const GLfloat * m
Definition: SDL_opengl_glext.h:6095
atan
double atan(double x)
Definition: s_atan.c:71
k
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display int int int return Display long XVisualInfo int return Display Window Atom long long Bool Atom Atom int unsigned long unsigned long k)
Definition: SDL_x11sym.h:80
zero
static const double zero
Definition: e_atan2.c:44
GET_HIGH_WORD
#define GET_HIGH_WORD(i, d)
Definition: math_private.h:109
pi_lo
static const double pi_lo
Definition: e_atan2.c:48