aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-07-01 22:27:49 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-07-01 22:27:49 +0000
commita04bb3306a9f9f17e5c588c903a438f1182ecd1a (patch)
tree41ea8bb67309f76a21a4269fd384518fee2cf000 /sysdeps
parented225df3ad9cbac3c22ec3f0fbbed1f9c61d1c54 (diff)
downloadglibc-a04bb3306a9f9f17e5c588c903a438f1182ecd1a.tar
glibc-a04bb3306a9f9f17e5c588c903a438f1182ecd1a.tar.gz
glibc-a04bb3306a9f9f17e5c588c903a438f1182ecd1a.tar.bz2
glibc-a04bb3306a9f9f17e5c588c903a438f1182ecd1a.zip
Fix ldbl-128 expm1l (-min_subnorm) result sign (bug 18619).
In the ldbl-128 implementation of expm1l, when expm1l's result should underflow to 0 (argument minus the least subnormal, in some rounding modes), it can be a zero of the wrong sign. This patch fixes this in the same way previously used for the x86 / x86_64 versions. Tested for mips64. [BZ #18619] * sysdeps/ieee754/ldbl-128/s_expm1l.c (__expm1l): Force underflow and return argument in case of subnormal argument.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/ieee754/ldbl-128/s_expm1l.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sysdeps/ieee754/ldbl-128/s_expm1l.c b/sysdeps/ieee754/ldbl-128/s_expm1l.c
index f708af504c..573d00be57 100644
--- a/sysdeps/ieee754/ldbl-128/s_expm1l.c
+++ b/sysdeps/ieee754/ldbl-128/s_expm1l.c
@@ -137,9 +137,18 @@ __expm1l (long double x)
if (x < minarg)
return (4.0/big - 1.0L);
- /* Avoid internal underflow when result does not underflow. */
- if (fabsl (x) < 0x1p-113L && fabsl (x) >= LDBL_MIN)
- return x;
+ /* Avoid internal underflow when result does not underflow, while
+ ensuring underflow (without returning a zero of the wrong sign)
+ when the result does underflow. */
+ if (fabsl (x) < 0x1p-113L)
+ {
+ if (fabsl (x) < LDBL_MIN)
+ {
+ long double force_underflow = x * x;
+ math_force_eval (force_underflow);
+ }
+ return x;
+ }
/* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
xx = C1 + C2; /* ln 2. */