Subversion Repositories Kolibri OS

Rev

Rev 4872 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
 
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
13
 
14
FUNCTION
15
	<>, <>---inverse hyperbolic sine
16
17
 
18
	asinh
19
INDEX
20
	asinhf
21
22
 
23
	#include 
24
	double asinh(double <[x]>);
25
	float asinhf(float <[x]>);
26
27
 
28
	#include 
29
	double asinh(<[x]>)
30
	double <[x]>;
31
32
 
33
	float <[x]>;
34
35
 
36
<> calculates the inverse hyperbolic sine of <[x]>.
37
<> is defined as
38
@ifnottex
39
. sgn(<[x]>) * log(abs(<[x]>) + sqrt(1+<[x]>*<[x]>))
40
@end ifnottex
41
@tex
42
$$sign(x) \times ln\Bigl(|x| + \sqrt{1+x^2}\Bigr)$$
43
@end tex
44
45
 
46
47
 
48
<> and <> return the calculated value.
49
50
 
51
Neither <> nor <> are ANSI C.
52
53
 
54
55
 
56
 * Method :
57
 *	Based on
58
 *		asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
59
 *	we have
60
 *	asinh(x) := x  if  1+x*x=1,
61
 *		 := sign(x)*(log(x)+ln2)) for large |x|, else
62
 *		 := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
63
 *		 := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
64
 */
65
66
 
67
68
 
69
70
 
71
static const double
72
#else
73
static double
74
#endif
75
one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
76
ln2 =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
77
huge=  1.00000000000000000000e+300;
78
79
 
80
	double asinh(double x)
81
#else
82
	double asinh(x)
83
	double x;
84
#endif
85
{
86
	double t,w;
87
	__int32_t hx,ix;
88
	GET_HIGH_WORD(hx,x);
89
	ix = hx&0x7fffffff;
90
	if(ix>=0x7ff00000) return x+x;	/* x is inf or NaN */
91
	if(ix< 0x3e300000) {	/* |x|<2**-28 */
92
	    if(huge+x>one) return x;	/* return x inexact except 0 */
93
	}
94
	if(ix>0x41b00000) {	/* |x| > 2**28 */
95
	    w = __ieee754_log(fabs(x))+ln2;
96
	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
97
	    t = fabs(x);
98
	    w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
99
	} else {		/* 2.0 > |x| > 2**-28 */
100
	    t = x*x;
101
	    w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
102
	}
103
	if(hx>0) return w; else return -w;
104
}
105
106
 
107