2bed1258a2ca9a87c88d4973c75dbb65c92499af
[musl] / src / math / coshf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/e_coshf.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 float coshf(float x)
19 {
20         union {float f; uint32_t i;} u = {.f = x};
21         uint32_t ix;
22         float t;
23
24         /* |x| */
25         u.i &= 0x7fffffff;
26         x = u.f;
27         ix = u.i;
28
29         /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
30         if (ix < 0x3eb17218) {
31                 t = expm1f(x);
32                 if (ix < 0x39800000)
33                         return 1;
34                 return 1 + t*t/(2*(1+t));
35         }
36
37         /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */
38         if (ix < 0x41100000) {
39                 t = expf(x);
40                 return 0.5f*t + 0.5f/t;
41         }
42
43         /* |x| in [9, log(maxfloat)] return 0.5f*exp(|x|) */
44         if (ix < 0x42b17217)
45                 return 0.5f*expf(x);
46
47         /* |x| in [log(maxfloat), overflowthresold] */
48         if (ix <= 0x42b2d4fc)
49                 return __expo2f(x);
50
51         /* |x| > overflowthresold or nan */
52         x *= 0x1p127f;
53         return x;
54 }