Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
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
#if defined(LIBM_SCCS) && !defined(lint)
15
static char rcsid[] = "$Id: e_atanh.c,v 1.6 1994/08/18 23:05:12 jtc Exp $";
16
#endif
17
 
18
/* __ieee754_atanh(x)
19
 * Method :
20
 *    1.Reduced x to positive by atanh(-x) = -atanh(x)
21
 *    2.For x>=0.5
22
 *                  1              2x                          x
23
 *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
24
 *                  2             1 - x                      1 - x
25
 *
26
 * 	For x<0.5
27
 *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
28
 *
29
 * Special cases:
30
 *	atanh(x) is NaN if |x| > 1 with signal;
31
 *	atanh(NaN) is that NaN with no signal;
32
 *	atanh(+-1) is +-INF with signal.
33
 *
34
 */
35
 
36
#include "math.h"
37
#include "math_private.h"
38
 
39
#ifdef __STDC__
40
static const double one = 1.0, huge = 1e300;
41
#else
42
static double one = 1.0, huge = 1e300;
43
#endif
44
 
45
#ifdef __STDC__
46
static const double zero = 0.0;
47
#else
48
static double zero = 0.0;
49
#endif
50
 
51
#ifdef __STDC__
52
	double __ieee754_atanh(double x)
53
#else
54
	double __ieee754_atanh(x)
55
	double x;
56
#endif
57
{
58
	double t;
59
	int32_t hx,ix;
60
	u_int32_t lx;
61
	EXTRACT_WORDS(hx,lx,x);
62
	ix = hx&0x7fffffff;
63
	if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
64
	    return (x-x)/(x-x);
65
	if(ix==0x3ff00000)
66
	    return x/zero;
67
	if(ix<0x3e300000&&(huge+x)>zero) return x;	/* x<2**-28 */
68
	SET_HIGH_WORD(x,ix);
69
	if(ix<0x3fe00000) {		/* x < 0.5 */
70
	    t = x+x;
71
	    t = 0.5*log1p(t+t*x/(one-x));
72
	} else
73
	    t = 0.5*log1p((x+x)/(one-x));
74
	if(hx>=0) return t; else return -t;
75
}