blob: dfadad09e5e5b0d51d5685354710811b79ad285d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
/* atanhf.c
*
* Inverse hyperbolic tangent
*
*
*
* SYNOPSIS:
*
* float x, y, atanhf();
*
* y = atanhf( x );
*
*
*
* DESCRIPTION:
*
* Returns inverse hyperbolic tangent of argument in the range
* MINLOGF to MAXLOGF.
*
* If |x| < 0.5, a polynomial approximation is used.
* Otherwise,
* atanh(x) = 0.5 * log( (1+x)/(1-x) ).
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE -1,1 100000 1.4e-7 3.1e-8
*
*/
/* atanh.c */
/*
Cephes Math Library Release 2.2: June, 1992
Copyright (C) 1987, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/* Single precision inverse hyperbolic tangent
* test interval: [-0.5, +0.5]
* trials: 10000
* peak relative error: 8.2e-8
* rms relative error: 3.0e-8
*/
#include <math.h>
extern float MAXNUMF;
float logf( float );
float atanhf( float xx )
{
float x, z;
x = xx;
if( x < 0 )
z = -x;
else
z = x;
if( z >= 1.0 )
{
if( x == 1.0 )
return( MAXNUMF );
if( x == -1.0 )
return( -MAXNUMF );
mtherr( "atanhl", DOMAIN );
return( MAXNUMF );
}
if( z < 1.0e-4 )
return(x);
if( z < 0.5 )
{
z = x * x;
z =
(((( 1.81740078349E-1 * z
+ 8.24370301058E-2) * z
+ 1.46691431730E-1) * z
+ 1.99782164500E-1) * z
+ 3.33337300303E-1) * z * x
+ x;
}
else
{
z = 0.5 * logf( (1.0+x)/(1.0-x) );
}
return( z );
}
|