aboutsummaryrefslogtreecommitdiff
path: root/math/exp.c
diff options
context:
space:
mode:
Diffstat (limited to 'math/exp.c')
-rw-r--r--math/exp.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/math/exp.c b/math/exp.c
index 9ee17e2..cc72780 100644
--- a/math/exp.c
+++ b/math/exp.c
@@ -40,10 +40,10 @@ specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
if ((ki & 0x80000000) == 0)
{
- /* k > 0, the exponent of scale might have overflowed by <= 85. */
- sbits -= 97ull << 52;
+ /* k > 0, the exponent of scale might have overflowed by <= 460. */
+ sbits -= 1009ull << 52;
scale = asdouble (sbits);
- y = 0x1p97 * (scale + scale * tmp);
+ y = 0x1p1009 * (scale + scale * tmp);
return check_oflow (y);
}
/* k < 0, need special care in the subnormal range. */
@@ -72,9 +72,9 @@ specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
}
static inline uint32_t
-top16 (double x)
+top12 (double x)
{
- return asuint64 (x) >> 48;
+ return asuint64 (x) >> 52;
}
static inline double
@@ -85,18 +85,18 @@ exp_inline (double x, double xtail, int hastail)
/* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
double_t kd, z, r, r2, scale, tail, tmp;
- abstop = top16 (x) & 0x7fff;
- if (unlikely (abstop - top16 (0x1p-54) >= top16 (704.0) - top16 (0x1p-54)))
+ abstop = top12 (x) & 0x7ff;
+ if (unlikely (abstop - top12 (0x1p-54) >= top12 (512.0) - top12 (0x1p-54)))
{
- if (abstop - top16 (0x1p-54) >= 0x80000000)
+ if (abstop - top12 (0x1p-54) >= 0x80000000)
/* Avoid spurious underflow for tiny x. */
/* Note: 0 is common input. */
return WANT_ROUNDING ? 1.0 + x : 1.0;
- if (abstop >= top16 (768.0))
+ if (abstop >= top12 (1024.0))
{
if (asuint64 (x) == asuint64 (-INFINITY))
return 0.0;
- if (abstop >= top16 (INFINITY))
+ if (abstop >= top12 (INFINITY))
return 1.0 + x;
if (asuint64 (x) >> 63)
return __math_uflow (0);
@@ -125,6 +125,7 @@ exp_inline (double x, double xtail, int hastail)
kd -= Shift;
#endif
r = x + kd*NegLn2hiN + kd*NegLn2loN;
+ /* The code assumes 2^-200 < |xtail| < 2^-8/N. */
if (hastail)
r += xtail;
/* 2^(k/N) ~= scale * (1 + tail). */
@@ -148,6 +149,8 @@ exp_inline (double x, double xtail, int hastail)
if (unlikely (abstop == 0))
return specialcase (tmp, sbits, ki);
scale = asdouble (sbits);
+ /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
+ is no spurious underflow here even without fma. */
return scale + scale * tmp;
}