1 #include "libm.h"
2 
tanhf(float x)3 float tanhf(float x) {
4     union {
5         float f;
6         uint32_t i;
7     } u = {.f = x};
8     uint32_t w;
9     int sign;
10     float t;
11 
12     /* x = |x| */
13     sign = u.i >> 31;
14     u.i &= 0x7fffffff;
15     x = u.f;
16     w = u.i;
17 
18     if (w > 0x3f0c9f54) {
19         /* |x| > log(3)/2 ~= 0.5493 or nan */
20         if (w > 0x41200000) {
21             /* |x| > 10 */
22             t = 1 + 0 / x;
23         } else {
24             t = expm1f(2 * x);
25             t = 1 - 2 / (t + 2);
26         }
27     } else if (w > 0x3e82c578) {
28         /* |x| > log(5/3)/2 ~= 0.2554 */
29         t = expm1f(2 * x);
30         t = t / (t + 2);
31     } else if (w >= 0x00800000) {
32         /* |x| >= 0x1p-126 */
33         t = expm1f(-2 * x);
34         t = -t / (t + 2);
35     } else {
36         /* |x| is subnormal */
37         FORCE_EVAL(x * x);
38         t = x;
39     }
40     return sign ? -t : t;
41 }
42