use #if LDBL_MANT_DIG == ... instead of custom LD80 etc macros
[libm] / src / math / sinhf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/e_sinhf.c */
2 /*
3  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4  */
5 /*
6  * ====================================================
7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8  *
9  * Developed at SunPro, a Sun Microsystems, Inc. business.
10  * Permission to use, copy, modify, and distribute this
11  * software is freely granted, provided that this notice
12  * is preserved.
13  * ====================================================
14  */
15
16 #include "libm.h"
17
18 static const float one = 1.0, huge = 1.0e37;
19
20 float sinhf(float x)
21 {
22         float t, h;
23         int32_t ix, jx;
24
25         GET_FLOAT_WORD(jx, x);
26         ix = jx & 0x7fffffff;
27
28         /* x is INF or NaN */
29         if (ix >= 0x7f800000)
30                 return x + x;
31
32         h = 0.5;
33         if (jx < 0)
34                 h = -h;
35         /* |x| in [0,9], return sign(x)*0.5*(E+E/(E+1))) */
36         if (ix < 0x41100000) {   /* |x|<9 */
37                 if (ix < 0x39800000)  /* |x|<2**-12 */
38                         /* raise inexact, return x */
39                         if (huge+x > one)
40                                 return x;
41                 t = expm1f(fabsf(x));
42                 if (ix < 0x3f800000)
43                         return h*((float)2.0*t - t*t/(t+one));
44                 return h*(t + t/(t+one));
45         }
46
47         /* |x| in [9, logf(maxfloat)] return 0.5*exp(|x|) */
48         if (ix < 0x42b17217)
49                 return h*expf(fabsf(x));
50
51         /* |x| in [logf(maxfloat), overflowthresold] */
52         if (ix <= 0x42b2d4fc)
53                 return h*2.0F*__ldexp_expf(fabsf(x), -1);
54
55         /* |x| > overflowthresold, sinh(x) overflow */
56         return x*huge;
57 }