math: rewrite inverse hyperbolic functions to be simpler/smaller
[musl] / src / math / atanhf.c
1 #include "libm.h"
2
3 /* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
4 float atanhf(float x)
5 {
6         union {float f; uint32_t i;} u = {.f = x};
7         unsigned s = u.i >> 31;
8
9         /* |x| */
10         u.i &= 0x7fffffff;
11         x = u.f;
12
13         if (u.i < 0x3f800000 - (1<<23)) {
14                 /* |x| < 0.5, up to 1.7ulp error */
15                 x = 0.5f*log1pf(2*x + 2*x*x/(1-x));
16         } else {
17                 x = 0.5f*log1pf(2*x/(1-x));
18         }
19         return s ? -x : x;
20 }