1 /* ef_atan2.c -- float version of e_atan2.c.
2 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3 */
4
5 /*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 *
15 */
16
17 #include "fdlibm.h"
18
19 static const float tiny = 1.0e-30, zero = 0.0,
20 pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */
21 pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */
22 pi = 3.1415927410e+00, /* 0x40490fdb */
23 pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
24
25 float
atan2f(float y,float x)26 atan2f(float y, float x)
27 {
28 float z;
29 __int32_t k, m, hx, hy, ix, iy;
30
31 GET_FLOAT_WORD(hx, x);
32 ix = hx & 0x7fffffff;
33 GET_FLOAT_WORD(hy, y);
34 iy = hy & 0x7fffffff;
35 if (FLT_UWORD_IS_NAN(ix) || FLT_UWORD_IS_NAN(iy)) /* x or y is NaN */
36 return x + y;
37 if (hx == 0x3f800000)
38 return atanf(y); /* x=1.0 */
39 m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
40
41 /* when y = 0 */
42 if (FLT_UWORD_IS_ZERO(iy)) {
43 switch (m) {
44 case 0:
45 case 1:
46 return y; /* atan(+-0,+anything)=+-0 */
47 case 2:
48 return pi + tiny; /* atan(+0,-anything) = pi */
49 case 3:
50 return -pi - tiny; /* atan(-0,-anything) =-pi */
51 }
52 }
53 /* when x = 0 */
54 if (FLT_UWORD_IS_ZERO(ix))
55 return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
56
57 /* when x is INF */
58 if (FLT_UWORD_IS_INFINITE(ix)) {
59 if (FLT_UWORD_IS_INFINITE(iy)) {
60 switch (m) {
61 case 0:
62 return pi_o_4 + tiny; /* atan(+INF,+INF) */
63 case 1:
64 return -pi_o_4 - tiny; /* atan(-INF,+INF) */
65 case 2:
66 return (float)3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/
67 case 3:
68 return (float)-3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/
69 }
70 } else {
71 switch (m) {
72 case 0:
73 return zero; /* atan(+...,+INF) */
74 case 1:
75 return -zero; /* atan(-...,+INF) */
76 case 2:
77 return pi + tiny; /* atan(+...,-INF) */
78 case 3:
79 return -pi - tiny; /* atan(-...,-INF) */
80 }
81 }
82 }
83 /* when y is INF */
84 if (FLT_UWORD_IS_INFINITE(iy))
85 return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
86
87 /* compute y/x */
88 k = (iy - ix) >> 23;
89 if (k > 60)
90 z = pi_o_2 + (float)0.5 * pi_lo; /* |y/x| > 2**60 */
91 else if (hx < 0 && k < -60)
92 z = 0.0f; /* |y|/x < -2**60 */
93 else
94 z = atanf(check_uflowf(fabsf(y / x))); /* safe to do y/x */
95 switch (m) {
96 case 0:
97 return z; /* atan(+,+) */
98 case 1: {
99 __uint32_t zh;
100 GET_FLOAT_WORD(zh, z);
101 SET_FLOAT_WORD(z, zh ^ 0x80000000);
102 }
103 return z; /* atan(-,+) */
104 case 2:
105 return pi - (z - pi_lo); /* atan(+,-) */
106 default: /* case 3 */
107 return (z - pi_lo) - pi; /* atan(-,-) */
108 }
109 }
110
111 _MATH_ALIAS_f_ff(atan2)
112