1 /* Return arc hyperbolic tangent for a complex float type.
2 Copyright (C) 1997-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 #include "quadmath-imp.h"
23 catanhq (__complex128 x
)
26 int rcls
= fpclassifyq (__real__ x
);
27 int icls
= fpclassifyq (__imag__ x
);
29 if (__glibc_unlikely (rcls
<= QUADFP_INFINITE
|| icls
<= QUADFP_INFINITE
))
31 if (icls
== QUADFP_INFINITE
)
33 __real__ res
= copysignq (0, __real__ x
);
34 __imag__ res
= copysignq (M_PI_2q
, __imag__ x
);
36 else if (rcls
== QUADFP_INFINITE
|| rcls
== QUADFP_ZERO
)
38 __real__ res
= copysignq (0, __real__ x
);
39 if (icls
>= QUADFP_ZERO
)
40 __imag__ res
= copysignq (M_PI_2q
, __imag__ x
);
42 __imag__ res
= nanq ("");
46 __real__ res
= nanq ("");
47 __imag__ res
= nanq ("");
50 else if (__glibc_unlikely (rcls
== QUADFP_ZERO
&& icls
== QUADFP_ZERO
))
56 if (fabsq (__real__ x
) >= 16 / FLT128_EPSILON
57 || fabsq (__imag__ x
) >= 16 / FLT128_EPSILON
)
59 __imag__ res
= copysignq (M_PI_2q
, __imag__ x
);
60 if (fabsq (__imag__ x
) <= 1)
61 __real__ res
= 1 / __real__ x
;
62 else if (fabsq (__real__ x
) <= 1)
63 __real__ res
= __real__ x
/ __imag__ x
/ __imag__ x
;
66 __float128 h
= hypotq (__real__ x
/ 2, __imag__ x
/ 2);
67 __real__ res
= __real__ x
/ h
/ h
/ 4;
72 if (fabsq (__real__ x
) == 1
73 && fabsq (__imag__ x
) < FLT128_EPSILON
* FLT128_EPSILON
)
74 __real__ res
= (copysignq (0.5Q
, __real__ x
)
75 * ((__float128
) M_LN2q
76 - logq (fabsq (__imag__ x
))));
80 if (fabsq (__imag__ x
) >= FLT128_EPSILON
* FLT128_EPSILON
)
81 i2
= __imag__ x
* __imag__ x
;
83 __float128 num
= 1 + __real__ x
;
86 __float128 den
= 1 - __real__ x
;
89 __float128 f
= num
/ den
;
91 __real__ res
= 0.25Q
* logq (f
);
95 __real__ res
= 0.25Q
* log1pq (num
/ den
);
99 __float128 absx
, absy
, den
;
101 absx
= fabsq (__real__ x
);
102 absy
= fabsq (__imag__ x
);
110 if (absy
< FLT128_EPSILON
/ 2)
112 den
= (1 - absx
) * (1 + absx
);
117 den
= (1 - absx
) * (1 + absx
) - absy
* absy
;
118 else if (absx
>= 0.75Q
|| absy
>= 0.5Q
)
119 den
= -__quadmath_x2y2m1q (absx
, absy
);
121 den
= (1 - absx
) * (1 + absx
) - absy
* absy
;
123 __imag__ res
= 0.5Q
* atan2q (2 * __imag__ x
, den
);
126 math_check_force_underflow_complex (res
);