1#include "libm.h"
2
3float coshf(float x) {
4    union {
5        float f;
6        uint32_t i;
7    } u = {.f = x};
8    uint32_t w;
9    float t;
10
11    /* |x| */
12    u.i &= 0x7fffffff;
13    x = u.f;
14    w = u.i;
15
16    /* |x| < log(2) */
17    if (w < 0x3f317217) {
18        if (w < 0x3f800000 - (12 << 23)) {
19            FORCE_EVAL(x + 0x1p120f);
20            return 1;
21        }
22        t = expm1f(x);
23        return 1 + t * t / (2 * (1 + t));
24    }
25
26    /* |x| < log(FLT_MAX) */
27    if (w < 0x42b17217) {
28        t = expf(x);
29        return 0.5f * (t + 1 / t);
30    }
31
32    /* |x| > log(FLT_MAX) or nan */
33    t = __expo2f(x);
34    return t;
35}
36