xref: /openbsd-src/lib/libm/src/ld128/s_asinhl.c (revision 49393c004c040ee201e6408db68882c3fe4cb110)
1*49393c00Smartynas /* @(#)s_asinh.c 5.1 93/09/24 */
2*49393c00Smartynas /*
3*49393c00Smartynas  * ====================================================
4*49393c00Smartynas  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5*49393c00Smartynas  *
6*49393c00Smartynas  * Developed at SunPro, a Sun Microsystems, Inc. business.
7*49393c00Smartynas  * Permission to use, copy, modify, and distribute this
8*49393c00Smartynas  * software is freely granted, provided that this notice
9*49393c00Smartynas  * is preserved.
10*49393c00Smartynas  * ====================================================
11*49393c00Smartynas  */
12*49393c00Smartynas 
13*49393c00Smartynas /* asinhl(x)
14*49393c00Smartynas  * Method :
15*49393c00Smartynas  *      Based on
16*49393c00Smartynas  *              asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ]
17*49393c00Smartynas  *      we have
18*49393c00Smartynas  *      asinhl(x) := x  if  1+x*x=1,
19*49393c00Smartynas  *                := signl(x)*(logl(x)+ln2)) for large |x|, else
20*49393c00Smartynas  *                := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else
21*49393c00Smartynas  *                := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2)))
22*49393c00Smartynas  */
23*49393c00Smartynas 
24*49393c00Smartynas #include <math.h>
25*49393c00Smartynas 
26*49393c00Smartynas #include "math_private.h"
27*49393c00Smartynas 
28*49393c00Smartynas static const long double
29*49393c00Smartynas   one = 1.0L,
30*49393c00Smartynas   ln2 = 6.931471805599453094172321214581765681e-1L,
31*49393c00Smartynas   huge = 1.0e+4900L;
32*49393c00Smartynas 
33*49393c00Smartynas long double
asinhl(long double x)34*49393c00Smartynas asinhl(long double x)
35*49393c00Smartynas {
36*49393c00Smartynas   long double t, w;
37*49393c00Smartynas   int32_t ix, sign;
38*49393c00Smartynas   ieee_quad_shape_type u;
39*49393c00Smartynas 
40*49393c00Smartynas   u.value = x;
41*49393c00Smartynas   sign = u.parts32.mswhi;
42*49393c00Smartynas   ix = sign & 0x7fffffff;
43*49393c00Smartynas   if (ix == 0x7fff0000)
44*49393c00Smartynas     return x + x;		/* x is inf or NaN */
45*49393c00Smartynas   if (ix < 0x3fc70000)
46*49393c00Smartynas     {				/* |x| < 2^ -56 */
47*49393c00Smartynas       if (huge + x > one)
48*49393c00Smartynas 	return x;		/* return x inexact except 0 */
49*49393c00Smartynas     }
50*49393c00Smartynas   u.parts32.mswhi = ix;
51*49393c00Smartynas   if (ix > 0x40350000)
52*49393c00Smartynas     {				/* |x| > 2 ^ 54 */
53*49393c00Smartynas       w = logl (u.value) + ln2;
54*49393c00Smartynas     }
55*49393c00Smartynas   else if (ix >0x40000000)
56*49393c00Smartynas     {				/* 2^ 54 > |x| > 2.0 */
57*49393c00Smartynas       t = u.value;
58*49393c00Smartynas       w = logl (2.0 * t + one / (sqrtl (x * x + one) + t));
59*49393c00Smartynas     }
60*49393c00Smartynas   else
61*49393c00Smartynas     {				/* 2.0 > |x| > 2 ^ -56 */
62*49393c00Smartynas       t = x * x;
63*49393c00Smartynas       w = log1pl (u.value + t / (one + sqrtl (one + t)));
64*49393c00Smartynas     }
65*49393c00Smartynas   if (sign & 0x80000000)
66*49393c00Smartynas     return -w;
67*49393c00Smartynas   else
68*49393c00Smartynas     return w;
69*49393c00Smartynas }
70