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 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