1 /*
2 * Copyright (c) 1985 Regents of the University of California.
3 *
4 * Use and reproduction of this software are granted in accordance with
5 * the terms and conditions specified in the Berkeley Software License
6 * Agreement (in particular, this entails acknowledgement of the programs'
7 * source, and inclusion of this notice) with the additional understanding
8 * that all recipients should regard themselves as participants in an
9 * ongoing research project and hence should feel obligated to report
10 * their experiences (good or bad) with these elementary function codes,
11 * using "sendbug 4bsd-bugs@BERKELEY", to the authors.
12 */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)atanh.c 1.2 (Berkeley) 08/21/85";
16 #endif not lint
17
18 /* ATANH(X)
19 * RETURN THE HYPERBOLIC ARC TANGENT OF X
20 * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
21 * CODED IN C BY K.C. NG, 1/8/85;
22 * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85.
23 *
24 * Required kernel function:
25 * log1p(x) ...return log(1+x)
26 *
27 * Method :
28 * Return
29 * 1 2x x
30 * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
31 * 2 1 - x 1 - x
32 *
33 * Special cases:
34 * atanh(x) is NaN if |x| > 1 with signal;
35 * atanh(NaN) is that NaN with no signal;
36 * atanh(+-1) is +-INF with signal.
37 *
38 * Accuracy:
39 * atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded.
40 * In a test run with 512,000 random arguments on a VAX, the maximum
41 * observed error was 1.87 ulps (units in the last place) at
42 * x= -3.8962076028810414000e-03.
43 */
44 #ifdef VAX
45 #include <errno.h>
46 #endif
47
atanh(x)48 double atanh(x)
49 double x;
50 {
51 double copysign(),log1p(),z;
52 z = copysign(0.5,x);
53 x = copysign(x,1.0);
54 #ifdef VAX
55 if (x == 1.0) {
56 extern double infnan();
57 return(copysign(1.0,z)*infnan(ERANGE)); /* sign(x)*INF */
58 }
59 #endif
60 x = x/(1.0-x);
61 return( z*log1p(x+x) );
62 }
63