X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmath%2Fatanhf.c;h=65f07c0f4f26e302f98ee4cc75b471c4204ee829;hb=76f440cff73878a7359e944618a7722dfd23bdec;hp=ca106efcbcba23f1d7219fb787567d315a206644;hpb=969ddbc423238291d5c7982790bbe72720627ba4;p=musl diff --git a/src/math/atanhf.c b/src/math/atanhf.c index ca106efc..65f07c0f 100644 --- a/src/math/atanhf.c +++ b/src/math/atanhf.c @@ -5,16 +5,24 @@ float atanhf(float x) { union {float f; uint32_t i;} u = {.f = x}; unsigned s = u.i >> 31; + float_t y; /* |x| */ u.i &= 0x7fffffff; - x = u.f; + y = u.f; if (u.i < 0x3f800000 - (1<<23)) { - /* |x| < 0.5, up to 1.7ulp error */ - x = 0.5f*log1pf(2*x + 2*x*x/(1-x)); + if (u.i < 0x3f800000 - (32<<23)) { + /* handle underflow */ + if (u.i < (1<<23)) + FORCE_EVAL((float)(y*y)); + } else { + /* |x| < 0.5, up to 1.7ulp error */ + y = 0.5f*log1pf(2*y + 2*y*y/(1-y)); + } } else { - x = 0.5f*log1pf(2*x/(1-x)); + /* avoid overflow */ + y = 0.5f*log1pf(2*(y/(1-y))); } - return s ? -x : x; + return s ? -y : y; }