summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authormartynas <martynas@openbsd.org>2011-05-30 22:23:59 +0000
committermartynas <martynas@openbsd.org>2011-05-30 22:23:59 +0000
commit2465a4bb43c580a47aeef035239318c2362cc766 (patch)
tree2afd869ba135faf60d6d5b505967f4ab1630903e /lib
parentEnable MSI. (diff)
downloadwireguard-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.c6
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 */