chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / sysdeps / ieee754 / ldbl-96 / e_sinhl.c
1 /* e_asinhl.c -- long double version of e_asinh.c.
2  * Conversion to long double by Ulrich Drepper,
3  * Cygnus Support, drepper@cygnus.com.
4  */
5
6 /*
7  * ====================================================
8  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9  *
10  * Developed at SunPro, a Sun Microsystems, Inc. business.
11  * Permission to use, copy, modify, and distribute this
12  * software is freely granted, provided that this notice
13  * is preserved.
14  * ====================================================
15  */
16
17 #if defined(LIBM_SCCS) && !defined(lint)
18 static char rcsid[] = "$NetBSD: $";
19 #endif
20
21 /* __ieee754_sinhl(x)
22  * Method :
23  * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
24  *      1. Replace x by |x| (sinhl(-x) = -sinhl(x)).
25  *      2.
26  *                                                   E + E/(E+1)
27  *          0        <= x <= 25     :  sinhl(x) := --------------, E=expm1l(x)
28  *                                                       2
29  *
30  *          25       <= x <= lnovft :  sinhl(x) := expl(x)/2
31  *          lnovft   <= x <= ln2ovft:  sinhl(x) := expl(x/2)/2 * expl(x/2)
32  *          ln2ovft  <  x           :  sinhl(x) := x*shuge (overflow)
33  *
34  * Special cases:
35  *      sinhl(x) is |x| if x is +INF, -INF, or NaN.
36  *      only sinhl(0)=0 is exact for finite x.
37  */
38
39 #include "math.h"
40 #include "math_private.h"
41
42 #ifdef __STDC__
43 static const long double one = 1.0, shuge = 1.0e4931L;
44 #else
45 static long double one = 1.0, shuge = 1.0e4931L;
46 #endif
47
48 #ifdef __STDC__
49         long double __ieee754_sinhl(long double x)
50 #else
51         long double __ieee754_sinhl(x)
52         long double x;
53 #endif
54 {
55         long double t,w,h;
56         u_int32_t jx,ix,i0,i1;
57
58     /* Words of |x|. */
59         GET_LDOUBLE_WORDS(jx,i0,i1,x);
60         ix = jx&0x7fff;
61
62     /* x is INF or NaN */
63         if(ix==0x7fff) return x+x;
64
65         h = 0.5;
66         if (jx & 0x8000) h = -h;
67     /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */
68         if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */
69             if (ix<0x3fdf)              /* |x|<2**-32 */
70                 if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
71             t = __expm1l(fabsl(x));
72             if(ix<0x3fff) return h*(2.0*t-t*t/(t+one));
73             return h*(t+t/(t+one));
74         }
75
76     /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */
77         if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7))
78                 return h*__ieee754_expl(fabsl(x));
79
80     /* |x| in [log(maxdouble), overflowthreshold] */
81         if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0
82                                            || (i0 == 0xb174ddc0
83                                                && i1 <= 0x31aec0ea)))) {
84             w = __ieee754_expl(0.5*fabsl(x));
85             t = h*w;
86             return t*w;
87         }
88
89     /* |x| > overflowthreshold, sinhl(x) overflow */
90         return x*shuge;
91 }