summaryrefslogtreecommitdiff
path: root/libquadmath/math/expm1q.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2017-07-31 14:43:24 +0200
committerMartin Jambor <mjambor@suse.cz>2017-07-31 14:43:24 +0200
commitb32f12dece884f1fa0f04c643a77105aff6ce8bc (patch)
treecdab5f10806561fc198f907299b0e55eb5701ef0 /libquadmath/math/expm1q.c
parent166bec868d991fdf71f9a66f994e5977fcab4aa2 (diff)
parenta168a775e93ec31ae743ad282d8e60fa1c116891 (diff)
downloadgcc-b32f12dece884f1fa0f04c643a77105aff6ce8bc.tar.gz
Merge branch 'master' into gcngcn
Diffstat (limited to 'libquadmath/math/expm1q.c')
-rw-r--r--libquadmath/math/expm1q.c33
1 files changed, 14 insertions, 19 deletions
diff --git a/libquadmath/math/expm1q.c b/libquadmath/math/expm1q.c
index 8cfdd8eec94..9060d480858 100644
--- a/libquadmath/math/expm1q.c
+++ b/libquadmath/math/expm1q.c
@@ -35,7 +35,7 @@
*
*/
-/* Copyright 2001 by Stephen L. Moshier
+/* Copyright 2001 by Stephen L. Moshier
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -82,8 +82,6 @@ static const __float128
C1 = 6.93145751953125E-1Q,
C2 = 1.428606820309417232121458176568075500134E-6Q,
-/* ln (2^16384 * (1 - 2^-113)) */
- maxlog = 1.1356523406294143949491931077970764891253E4Q,
/* ln 2^-114 */
minarg = -7.9018778583833765273564461846232128760607E1Q;
@@ -108,33 +106,30 @@ expm1q (__float128 x)
}
if (ix >= 0x7fff0000)
{
- /* Infinity. */
+ /* Infinity (which must be negative infinity). */
if (((ix & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3) == 0)
- {
- if (sign)
- return -1.0Q;
- else
- return x;
- }
- /* NaN. No invalid exception. */
- return x;
+ return -1.0Q;
+ /* NaN. Invalid exception if signaling. */
+ return x + x;
}
/* expm1(+- 0) = +- 0. */
if ((ix == 0) && (u.words32.w1 | u.words32.w2 | u.words32.w3) == 0)
return x;
- /* Overflow. */
- if (x > maxlog)
- {
- errno = ERANGE;
- return (HUGE_VALQ * HUGE_VALQ);
- }
-
/* Minimum value. */
if (x < minarg)
return (4.0/HUGE_VALQ - 1.0Q);
+ /* 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 (fabsq (x) < 0x1p-113Q)
+ {
+ math_check_force_underflow (x);
+ return x;
+ }
+
/* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
xx = C1 + C2; /* ln 2. */
px = floorq (0.5 + x / xx);