1 
2 /* @(#)e_atanh.c 5.1 93/09/24 */
3 /*
4  * ====================================================
5  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6  *
7  * Developed at SunPro, a Sun Microsystems, Inc. business.
8  * Permission to use, copy, modify, and distribute this
9  * software is freely granted, provided that this notice
10  * is preserved.
11  * ====================================================
12  *
13  */
14 
15 /* atanh(x)
16  * Method :
17  *    1.Reduced x to positive by atanh(-x) = -atanh(x)
18  *    2.For x>=0.5
19  *                  1              2x                          x
20  *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
21  *                  2             1 - x                      1 - x
22  *
23  * 	For x<0.5
24  *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
25  *
26  * Special cases:
27  *	atanh(x) is NaN if |x| > 1 with signal;
28  *	atanh(NaN) is that NaN with no signal;
29  *	atanh(+-1) is +-INF with signal.
30  *
31  */
32 
33 #include "fdlibm.h"
34 
35 #ifdef _NEED_FLOAT64
36 
37 static const __float64 one = _F_64(1.0), huge = _F_64(1e300);
38 
39 static const __float64 zero = _F_64(0.0);
40 
41 __float64
atanh64(__float64 x)42 atanh64(__float64 x)
43 {
44     __float64 t;
45     __int32_t hx, ix;
46     __uint32_t lx;
47     EXTRACT_WORDS(hx, lx, x);
48     ix = hx & 0x7fffffff;
49     if ((ix | ((lx | (-lx)) >> 31)) > 0x3ff00000) /* |x|>1 */
50         return __math_invalid(x);
51     if (ix == 0x3ff00000)
52         return __math_divzero(x < 0);
53     if (ix < 0x3e300000 && (huge + x) > zero)
54         return x; /* x<2**-28 */
55     SET_HIGH_WORD(x, ix);
56     if (ix < 0x3fe00000) { /* x < 0.5 */
57         t = x + x;
58         t = _F_64(0.5) * log1p64(t + t * x / (one - x));
59     } else
60         t = _F_64(0.5) * log1p64((x + x) / (one - x));
61     if (hx >= 0)
62         return t;
63     else
64         return -t;
65 }
66 
67 _MATH_ALIAS_d_d(atanh)
68 
69 #endif /* _NEED_FLOAT64 */
70