diff options
author | 2011-05-30 22:23:59 +0000 | |
---|---|---|
committer | 2011-05-30 22:23:59 +0000 | |
commit | 2465a4bb43c580a47aeef035239318c2362cc766 (patch) | |
tree | 2afd869ba135faf60d6d5b505967f4ab1630903e /lib | |
parent | Enable MSI. (diff) | |
download | wireguard-openbsd-2465a4bb43c580a47aeef035239318c2362cc766.tar.xz wireguard-openbsd-2465a4bb43c580a47aeef035239318c2362cc766.zip |
For tiny x, tanh = x*(one+x). GCC (at -O2) optimized this into
x+x*x, as a result sign got lost for the input of -0. Explicitly
return negative zero in this case. Found by Cephes.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libm/src/s_tanh.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/libm/src/s_tanh.c b/lib/libm/src/s_tanh.c index 1564c47855d..c5730590dfc 100644 --- a/lib/libm/src/s_tanh.c +++ b/lib/libm/src/s_tanh.c @@ -43,10 +43,10 @@ double tanh(double x) { double t,z; - int32_t jx,ix; + int32_t jx,ix,lx; /* High word of |x|. */ - GET_HIGH_WORD(jx,x); + EXTRACT_WORDS(jx,lx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ @@ -57,6 +57,8 @@ tanh(double x) /* |x| < 22 */ if (ix < 0x40360000) { /* |x|<22 */ + if ((ix | lx) == 0) + return x; /* x == +-0 */ if (ix<0x3c800000) /* |x|<2**-55 */ return x*(one+x); /* tanh(small) = small */ if (ix>=0x3ff00000) { /* |x|>=1 */ |