summaryrefslogtreecommitdiff
path: root/src/math/exp2f.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/exp2f.c')
-rw-r--r--src/math/exp2f.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/src/math/exp2f.c b/src/math/exp2f.c
index 55c22eac..279f32de 100644
--- a/src/math/exp2f.c
+++ b/src/math/exp2f.c
@@ -27,19 +27,15 @@
#include "libm.h"
-#define TBLBITS 4
-#define TBLSIZE (1 << TBLBITS)
+#define TBLSIZE 16
static const float
-huge = 0x1p100f,
redux = 0x1.8p23f / TBLSIZE,
P1 = 0x1.62e430p-1f,
P2 = 0x1.ebfbe0p-3f,
P3 = 0x1.c6b348p-5f,
P4 = 0x1.3b2c9cp-7f;
-static const volatile float twom100 = 0x1p-100f;
-
static const double exp2ft[TBLSIZE] = {
0x1.6a09e667f3bcdp-1,
0x1.7a11473eb0187p-1,
@@ -89,23 +85,25 @@ float exp2f(float x)
{
double tv, twopk, u, z;
float t;
- uint32_t hx, ix, i0;
- int32_t k;
+ uint32_t hx, ix, i0, k;
/* Filter out exceptional cases. */
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix >= 0x43000000) { /* |x| >= 128 */
if (ix >= 0x7f800000) {
- if ((ix & 0x7fffff) != 0 || (hx & 0x80000000) == 0)
- return x + x; /* x is NaN or +Inf */
- else
- return 0.0; /* x is -Inf */
+ if (hx == 0xff800000) /* -inf */
+ return 0;
+ return x;
+ }
+ if (x >= 128) {
+ STRICT_ASSIGN(float, x, x * 0x1p127);
+ return x;
+ }
+ if (x <= -150) {
+ STRICT_ASSIGN(float, x, 0x1p-100*0x1p-100);
+ return x;
}
- if (x >= 0x1.0p7f)
- return huge * huge; /* overflow */
- if (x <= -0x1.2cp7f)
- return twom100 * twom100; /* underflow */
} else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */
return 1.0f + x;
}
@@ -114,7 +112,7 @@ float exp2f(float x)
STRICT_ASSIGN(float, t, x + redux);
GET_FLOAT_WORD(i0, t);
i0 += TBLSIZE / 2;
- k = (i0 >> TBLBITS) << 20;
+ k = (i0 / TBLSIZE) << 20;
i0 &= TBLSIZE - 1;
t -= redux;
z = x - t;