Remove "Contributed by" lines
[platform/upstream/glibc.git] / math / s_catan_template.c
1 /* Return arc tangent of complex float type.
2    Copyright (C) 1997-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18
19 #include <complex.h>
20 #include <math.h>
21 #include <math_private.h>
22 #include <math-underflow.h>
23 #include <float.h>
24
25 CFLOAT
26 M_DECL_FUNC (__catan) (CFLOAT x)
27 {
28   CFLOAT res;
29   int rcls = fpclassify (__real__ x);
30   int icls = fpclassify (__imag__ x);
31
32   if (__glibc_unlikely (rcls <= FP_INFINITE || icls <= FP_INFINITE))
33     {
34       if (rcls == FP_INFINITE)
35         {
36           __real__ res = M_COPYSIGN (M_MLIT (M_PI_2), __real__ x);
37           __imag__ res = M_COPYSIGN (0, __imag__ x);
38         }
39       else if (icls == FP_INFINITE)
40         {
41           if (rcls >= FP_ZERO)
42             __real__ res = M_COPYSIGN (M_MLIT (M_PI_2), __real__ x);
43           else
44             __real__ res = M_NAN;
45           __imag__ res = M_COPYSIGN (0, __imag__ x);
46         }
47       else if (icls == FP_ZERO || icls == FP_INFINITE)
48         {
49           __real__ res = M_NAN;
50           __imag__ res = M_COPYSIGN (0, __imag__ x);
51         }
52       else
53         {
54           __real__ res = M_NAN;
55           __imag__ res = M_NAN;
56         }
57     }
58   else if (__glibc_unlikely (rcls == FP_ZERO && icls == FP_ZERO))
59     {
60       res = x;
61     }
62   else
63     {
64       if (M_FABS (__real__ x) >= 16 / M_EPSILON
65           || M_FABS (__imag__ x) >= 16 / M_EPSILON)
66         {
67           __real__ res = M_COPYSIGN (M_MLIT (M_PI_2), __real__ x);
68           if (M_FABS (__real__ x) <= 1)
69             __imag__ res = 1 / __imag__ x;
70           else if (M_FABS (__imag__ x) <= 1)
71             __imag__ res = __imag__ x / __real__ x / __real__ x;
72           else
73             {
74               FLOAT h = M_HYPOT (__real__ x / 2, __imag__ x / 2);
75               __imag__ res = __imag__ x / h / h / 4;
76             }
77         }
78       else
79         {
80           FLOAT den, absx, absy;
81
82           absx = M_FABS (__real__ x);
83           absy = M_FABS (__imag__ x);
84           if (absx < absy)
85             {
86               FLOAT t = absx;
87               absx = absy;
88               absy = t;
89             }
90
91           if (absy < M_EPSILON / 2)
92             {
93               den = (1 - absx) * (1 + absx);
94               if (den == 0)
95                 den = 0;
96             }
97           else if (absx >= 1)
98             den = (1 - absx) * (1 + absx) - absy * absy;
99           else if (absx >= M_LIT (0.75) || absy >= M_LIT (0.5))
100             den = -M_SUF (__x2y2m1) (absx, absy);
101           else
102             den = (1 - absx) * (1 + absx) - absy * absy;
103
104           __real__ res = M_LIT (0.5) * M_ATAN2 (2 * __real__ x, den);
105
106           if (M_FABS (__imag__ x) == 1
107               && M_FABS (__real__ x) < M_EPSILON * M_EPSILON)
108             __imag__ res = (M_COPYSIGN (M_LIT (0.5), __imag__ x)
109                             * ((FLOAT) M_MLIT (M_LN2)
110                                - M_LOG (M_FABS (__real__ x))));
111           else
112             {
113               FLOAT r2 = 0, num, f;
114
115               if (M_FABS (__real__ x) >= M_EPSILON * M_EPSILON)
116                 r2 = __real__ x * __real__ x;
117
118               num = __imag__ x + 1;
119               num = r2 + num * num;
120
121               den = __imag__ x - 1;
122               den = r2 + den * den;
123
124               f = num / den;
125               if (f < M_LIT (0.5))
126                 __imag__ res = M_LIT (0.25) * M_LOG (f);
127               else
128                 {
129                   num = 4 * __imag__ x;
130                   __imag__ res = M_LIT (0.25) * M_LOG1P (num / den);
131                 }
132             }
133         }
134
135       math_check_force_underflow_complex (res);
136     }
137
138   return res;
139 }
140
141 declare_mgen_alias (__catan, catan)