summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pow_z.c20
-rw-r--r--tests/tpow_z.c40
2 files changed, 49 insertions, 11 deletions
diff --git a/pow_z.c b/pow_z.c
index ab1efa6b6..23170b20e 100644
--- a/pow_z.c
+++ b/pow_z.c
@@ -81,21 +81,19 @@ mpfr_pow_pos_z (mpfr_ptr y, mpfr_srcptr x, mpz_srcptr z, mp_rnd_t rnd)
}
MPFR_ZIV_FREE (loop);
- inexact = mpfr_set (y, res, rnd);
- mpfr_clear (res);
-
/* Check Overflow */
if (MPFR_UNLIKELY (mpfr_overflow_p ()))
- return mpfr_overflow (y, rnd,
- mpz_odd_p (absz) ? MPFR_SIGN (x) : MPFR_SIGN_POS);
+ inexact = mpfr_overflow (y, rnd, mpz_odd_p (absz) ?
+ MPFR_SIGN (x) : MPFR_SIGN_POS);
/* Check Underflow */
else if (MPFR_UNLIKELY (mpfr_underflow_p ()))
- {
- if (rnd == GMP_RNDN)
- rnd = GMP_RNDZ;
- return mpfr_underflow (y, rnd,
- mpz_odd_p (absz) ? MPFR_SIGN (x) : MPFR_SIGN_POS);
- }
+ inexact = mpfr_underflow (y, rnd == GMP_RNDN ? GMP_RNDZ : rnd,
+ mpz_odd_p (absz) ? MPFR_SIGN (x) :
+ MPFR_SIGN_POS);
+ else
+ inexact = mpfr_set (y, res, rnd);
+
+ mpfr_clear (res);
return inexact;
}
diff --git a/tests/tpow_z.c b/tests/tpow_z.c
index 0fb71ba19..d4da4ecbe 100644
--- a/tests/tpow_z.c
+++ b/tests/tpow_z.c
@@ -257,6 +257,45 @@ bug20071104 (void)
mpz_clear (z);
}
+static void
+check_overflow (void)
+{
+ mpfr_t a;
+ mpz_t z;
+ unsigned long n;
+ int res;
+
+ mpfr_init2 (a, 53);
+
+ mpfr_set_str_binary (a, "1E10");
+ mpz_init_set_ui (z, ULONG_MAX);
+ res = mpfr_pow_z (a, a, z, GMP_RNDN);
+ if (!MPFR_IS_INF (a) || MPFR_SIGN (a) < 0)
+ {
+ printf ("Error for (1e10)^ULONG_MAX\n");
+ exit (1);
+ }
+
+ /* Bug in pow_z.c up to r5109: if x = y (same mpfr_t argument), the
+ input argument is negative and not a power of two, z is positive
+ and odd, an overflow or underflow occurs, and the temporary result
+ res is positive, then the result gets a wrong sign (positive
+ instead of negative). */
+ mpfr_set_str_binary (a, "-1.1E10");
+ n = (ULONG_MAX ^ (ULONG_MAX >> 1)) + 1;
+ mpz_set_ui (z, n);
+ res = mpfr_pow_z (a, a, z, GMP_RNDN);
+ if (!MPFR_IS_INF (a) || MPFR_SIGN (a) > 0)
+ {
+ printf ("Error for (-1e10)^%lu, expected -Inf,\ngot ", n);
+ mpfr_dump (a);
+ exit (1);
+ }
+
+ mpfr_clear (a);
+ mpz_clear (z);
+}
+
int
main (void)
{
@@ -266,6 +305,7 @@ main (void)
check_integer (2, 163, 100);
check_regression ();
bug20071104 ();
+ check_overflow ();
tests_end_mpfr ();
return 0;