math: tanh.c cleanup similar to sinh, cosh
[musl] / src / math / tanhf.c
1 #include "libm.h"
2
3 float tanhf(float x)
4 {
5         union {float f; uint32_t i;} u = {.f = x};
6         uint32_t w;
7         int sign;
8         float t;
9
10         /* x = |x| */
11         sign = u.i >> 31;
12         u.i &= 0x7fffffff;
13         x = u.f;
14         w = u.i;
15
16         if (w > 0x3f0c9f54) {
17                 /* |x| > log(3)/2 ~= 0.5493 or nan */
18                 if (w > 0x41200000) {
19                         /* |x| > 10 */
20                         t = 1 + 0/(x + 0x1p-120f);
21                 } else {
22                         t = expm1f(2*x);
23                         t = 1 - 2/(t+2);
24                 }
25         } else if (w > 0x3e82c578) {
26                 /* |x| > log(5/3)/2 ~= 0.2554 */
27                 t = expm1f(2*x);
28                 t = t/(t+2);
29         } else {
30                 /* |x| is small */
31                 t = expm1f(-2*x);
32                 t = -t/(t+2);
33         }
34         return sign ? -t : t;
35 }