Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / lib / msun / src / e_atanh.c
1 /* @(#)e_atanh.c 5.1 93/09/24 */
2 /*
3  * ====================================================
4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5  *
6  * Developed at SunPro, a Sun Microsystems, Inc. business.
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  *
12  * $FreeBSD: src/lib/msun/src/e_atanh.c,v 1.5 1999/08/28 00:06:29 peter Exp $
13  * $DragonFly: src/lib/msun/src/Attic/e_atanh.c,v 1.2 2003/06/17 04:26:52 dillon Exp $
14  */
15
16 /* __ieee754_atanh(x)
17  * Method :
18  *    1.Reduced x to positive by atanh(-x) = -atanh(x)
19  *    2.For x>=0.5
20  *                  1              2x                          x
21  *      atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
22  *                  2             1 - x                      1 - x
23  *
24  *      For x<0.5
25  *      atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
26  *
27  * Special cases:
28  *      atanh(x) is NaN if |x| > 1 with signal;
29  *      atanh(NaN) is that NaN with no signal;
30  *      atanh(+-1) is +-INF with signal.
31  *
32  */
33
34 #include "math.h"
35 #include "math_private.h"
36
37 #ifdef __STDC__
38 static const double one = 1.0, huge = 1e300;
39 #else
40 static double one = 1.0, huge = 1e300;
41 #endif
42
43 #ifdef __STDC__
44 static const double zero = 0.0;
45 #else
46 static double zero = 0.0;
47 #endif
48
49 #ifdef __STDC__
50         double __ieee754_atanh(double x)
51 #else
52         double __ieee754_atanh(x)
53         double x;
54 #endif
55 {
56         double t;
57         int32_t hx,ix;
58         u_int32_t lx;
59         EXTRACT_WORDS(hx,lx,x);
60         ix = hx&0x7fffffff;
61         if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
62             return (x-x)/(x-x);
63         if(ix==0x3ff00000)
64             return x/zero;
65         if(ix<0x3e300000&&(huge+x)>zero) return x;      /* x<2**-28 */
66         SET_HIGH_WORD(x,ix);
67         if(ix<0x3fe00000) {             /* x < 0.5 */
68             t = x+x;
69             t = 0.5*log1p(t+t*x/(one-x));
70         } else
71             t = 0.5*log1p((x+x)/(one-x));
72         if(hx>=0) return t; else return -t;
73 }