• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * This file is based on work under the following copyright and permission
16  * notice:
17  *
18  *     Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19  *
20  *     Developed at SunSoft, a Sun Microsystems, Inc. business.
21  *     Permission to use, copy, modify, and distribute this
22  *     software is freely granted, provided that this notice
23  *     is preserved.
24  *
25  *     @(#)e_atan2.c 1.3 95/01/18
26  */
27 
28 #include "jerry-libm-internal.h"
29 
30 /* atan2(y,x)
31  *
32  * Method:
33  *      1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
34  *      2. Reduce x to positive by (if x and y are unexceptional):
35  *              ARG (x+iy) = arctan(y/x)           ... if x > 0,
36  *              ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
37  *
38  * Special cases:
39  *      ATAN2((anything), NaN ) is NaN;
40  *      ATAN2(NAN , (anything) ) is NaN;
41  *      ATAN2(+-0, +(anything but NaN)) is +-0  ;
42  *      ATAN2(+-0, -(anything but NaN)) is +-pi ;
43  *      ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
44  *      ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
45  *      ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
46  *      ATAN2(+-INF,+INF ) is +-pi/4 ;
47  *      ATAN2(+-INF,-INF ) is +-3pi/4;
48  *      ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
49  *
50  * Constants:
51  * The hexadecimal values are the intended ones for the following
52  * constants. The decimal values may be used, provided that the
53  * compiler will convert from decimal to binary accurately enough
54  * to produce the hexadecimal values shown.
55  */
56 
57 #define tiny   1.0e-300
58 #define zero   0.0
59 #define pi_o_4 7.8539816339744827900E-01 /* 0x3FE921FB, 0x54442D18 */
60 #define pi_o_2 1.5707963267948965580E+00 /* 0x3FF921FB, 0x54442D18 */
61 #define pi     3.1415926535897931160E+00 /* 0x400921FB, 0x54442D18 */
62 #define pi_lo  1.2246467991473531772E-16 /* 0x3CA1A626, 0x33145C07 */
63 
64 double
atan2(double y,double x)65 atan2 (double y, double x)
66 {
67   double_accessor z;
68   int k, m, hx, hy, ix, iy;
69   unsigned lx, ly;
70 
71   hx = __HI (x);
72   ix = hx & 0x7fffffff;
73   lx = __LO (x);
74   hy = __HI (y);
75   iy = hy & 0x7fffffff;
76   ly = __LO (y);
77   if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000) || ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* x or y is NaN */
78   {
79     return x + y;
80   }
81   if (((hx - 0x3ff00000) | lx) == 0) /* x = 1.0 */
82   {
83     return atan (y);
84   }
85   m = ((hy < 0) ? 1 : 0) + ((hx < 0) ? 2 : 0); /* 2 * sign(x) + sign(y) */
86 
87   /* when y = 0 */
88   if ((iy | ly) == 0)
89   {
90     switch (m)
91     {
92       case 0:
93       case 1:
94       {
95         return y; /* atan(+-0,+anything) = +-0 */
96       }
97       case 2:
98       {
99         return pi + tiny; /* atan(+0,-anything) = pi */
100       }
101       case 3:
102       {
103         return -pi - tiny; /* atan(-0,-anything) = -pi */
104       }
105     }
106   }
107   /* when x = 0 */
108   if ((ix | lx) == 0)
109   {
110     return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
111   }
112 
113   /* when x is INF */
114   if (ix == 0x7ff00000)
115   {
116     if (iy == 0x7ff00000)
117     {
118       switch (m)
119       {
120         case 0: /* atan(+INF,+INF) */
121         {
122           return pi_o_4 + tiny;
123         }
124         case 1: /* atan(-INF,+INF) */
125         {
126           return -pi_o_4 - tiny;
127         }
128         case 2: /* atan(+INF,-INF) */
129         {
130           return 3.0 * pi_o_4 + tiny;
131         }
132         case 3: /* atan(-INF,-INF) */
133         {
134           return -3.0 * pi_o_4 - tiny;
135         }
136       }
137     }
138     else
139     {
140       switch (m)
141       {
142         case 0: /* atan(+...,+INF) */
143         {
144           return zero;
145         }
146         case 1: /* atan(-...,+INF) */
147         {
148           return -zero;
149         }
150         case 2: /* atan(+...,-INF) */
151         {
152           return pi + tiny;
153         }
154         case 3: /* atan(-...,-INF) */
155         {
156           return -pi - tiny;
157         }
158       }
159     }
160   }
161   /* when y is INF */
162   if (iy == 0x7ff00000)
163   {
164     return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
165   }
166 
167   /* compute y / x */
168   k = (iy - ix) >> 20;
169   if (k > 60) /* |y / x| > 2**60 */
170   {
171     z.dbl = pi_o_2 + 0.5 * pi_lo;
172   }
173   else if (hx < 0 && k < -60) /* |y| / x < -2**60 */
174   {
175     z.dbl = 0.0;
176   }
177   else /* safe to do y / x */
178   {
179     z.dbl = atan (fabs (y / x));
180   }
181   switch (m)
182   {
183     case 0: /* atan(+,+) */
184     {
185       return z.dbl;
186     }
187     case 1: /* atan(-,+) */
188     {
189       z.as_int.hi ^= 0x80000000;
190       return z.dbl;
191     }
192     case 2: /* atan(+,-) */
193     {
194       return pi - (z.dbl - pi_lo);
195     }
196     /* case 3: */
197     default: /* atan(-,-) */
198     {
199       return (z.dbl - pi_lo) - pi;
200     }
201   }
202 } /* atan2 */
203 
204 #undef tiny
205 #undef zero
206 #undef pi_o_4
207 #undef pi_o_2
208 #undef pi
209 #undef pi_lo
210