source: trunk/libs/newlib/src/newlib/libm/mathfp/e_atanh.c @ 471

Last change on this file since 471 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.9 KB
Line 
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/*
16FUNCTION
17        <<atanh>>, <<atanhf>>---inverse hyperbolic tangent
18
19INDEX
20        atanh
21INDEX
22        atanhf
23
24SYNOPSIS
25        #include <math.h>
26        double atanh(double <[x]>);
27        float atanhf(float <[x]>);
28
29DESCRIPTION
30        <<atanh>> calculates the inverse hyperbolic tangent of <[x]>.
31
32        <<atanhf>> is identical, other than taking and returning
33        <<float>> values.
34
35RETURNS
36        <<atanh>> and <<atanhf>> return the calculated value.
37
38        If
39        @ifnottex
40        |<[x]>|
41        @end ifnottex
42        @tex
43        $|x|$
44        @end tex
45        is greater than 1, the global <<errno>> is set to <<EDOM>> and
46        the result is a NaN.  A <<DOMAIN error>> is reported.
47
48        If
49        @ifnottex
50        |<[x]>|
51        @end ifnottex
52        @tex
53        $|x|$
54        @end tex
55        is 1, the global <<errno>> is set to <<EDOM>>; and the result is
56        infinity with the same sign as <<x>>.  A <<SING error>> is reported.
57
58        You can modify the error handling for these routines using
59        <<matherr>>.
60
61PORTABILITY
62        Neither <<atanh>> nor <<atanhf>> are ANSI C.
63
64QUICKREF
65        atanh - pure
66        atanhf - pure
67
68
69*/
70
71/* atanh(x)
72 * Method :
73 *    1.Reduced x to positive by atanh(-x) = -atanh(x)
74 *    2.For x>=0.5
75 *                  1              2x                          x
76 *      atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
77 *                  2             1 - x                      1 - x
78 *     
79 *      For x<0.5
80 *      atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
81 *
82 * Special cases:
83 *      atanh(x) is NaN if |x| > 1 with signal;
84 *      atanh(NaN) is that NaN with no signal;
85 *      atanh(+-1) is +-INF with signal.
86 *
87 */
88
89#include "fdlibm.h"
90
91#ifndef _DOUBLE_IS_32BITS
92
93#ifdef __STDC__
94static const double one = 1.0, huge = 1e300;
95#else
96static double one = 1.0, huge = 1e300;
97#endif
98
99#ifdef __STDC__
100static const double zero = 0.0;
101#else
102static double zero = 0.0;
103#endif
104
105#ifdef __STDC__
106        double atanh(double x)
107#else
108        double atanh(x)
109        double x;
110#endif
111{
112        double t;
113        __int32_t hx,ix;
114        __uint32_t lx;
115        EXTRACT_WORDS(hx,lx,x);
116        ix = hx&0x7fffffff;
117        if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
118            return (x-x)/(x-x);
119        if(ix==0x3ff00000) 
120            return x/zero;
121        if(ix<0x3e300000&&(huge+x)>zero) return x;      /* x<2**-28 */
122        SET_HIGH_WORD(x,ix);
123        if(ix<0x3fe00000) {             /* x < 0.5 */
124            t = x+x;
125            t = 0.5*log1p(t+t*x/(one-x));
126        } else 
127            t = 0.5*log1p((x+x)/(one-x));
128        if(hx>=0) return t; else return -t;
129}
130
131#endif /* defined(_DOUBLE_IS_32BITS) */
Note: See TracBrowser for help on using the repository browser.