diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES --- mpfr-3.1.2-a/PATCHES 2014-06-30 15:15:25.533266905 +0000 +++ mpfr-3.1.2-b/PATCHES 2014-06-30 15:15:25.617269178 +0000 @@ -0,0 +1 @@ +div-overflow diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION --- mpfr-3.1.2-a/VERSION 2014-06-30 15:15:25.529266797 +0000 +++ mpfr-3.1.2-b/VERSION 2014-06-30 15:15:25.617269178 +0000 @@ -1 +1 @@ -3.1.2-p8 +3.1.2-p9 diff -Naurd mpfr-3.1.2-a/src/div.c mpfr-3.1.2-b/src/div.c --- mpfr-3.1.2-a/src/div.c 2013-03-13 15:37:33.000000000 +0000 +++ mpfr-3.1.2-b/src/div.c 2014-06-30 15:15:25.585268312 +0000 @@ -750,7 +750,9 @@ truncate_check_qh: if (qh) { - qexp ++; + if (MPFR_LIKELY (qexp < MPFR_EXP_MAX)) + qexp ++; + /* else qexp is now incorrect, but one will still get an overflow */ q0p[q0size - 1] = MPFR_LIMB_HIGHBIT; } goto truncate; @@ -765,7 +767,9 @@ inex = 1; /* always here */ if (mpn_add_1 (q0p, q0p, q0size, MPFR_LIMB_ONE << sh)) { - qexp ++; + if (MPFR_LIKELY (qexp < MPFR_EXP_MAX)) + qexp ++; + /* else qexp is now incorrect, but one will still get an overflow */ q0p[q0size - 1] = MPFR_LIMB_HIGHBIT; } diff -Naurd mpfr-3.1.2-a/src/mpfr.h mpfr-3.1.2-b/src/mpfr.h --- mpfr-3.1.2-a/src/mpfr.h 2014-06-30 15:15:25.533266905 +0000 +++ mpfr-3.1.2-b/src/mpfr.h 2014-06-30 15:15:25.613269070 +0000 @@ -27,7 +27,7 @@ #define MPFR_VERSION_MAJOR 3 #define MPFR_VERSION_MINOR 1 #define MPFR_VERSION_PATCHLEVEL 2 -#define MPFR_VERSION_STRING "3.1.2-p8" +#define MPFR_VERSION_STRING "3.1.2-p9" /* Macros dealing with MPFR VERSION */ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) diff -Naurd mpfr-3.1.2-a/src/version.c mpfr-3.1.2-b/src/version.c --- mpfr-3.1.2-a/src/version.c 2014-06-30 15:15:25.533266905 +0000 +++ mpfr-3.1.2-b/src/version.c 2014-06-30 15:15:25.613269070 +0000 @@ -25,5 +25,5 @@ const char * mpfr_get_version (void) { - return "3.1.2-p8"; + return "3.1.2-p9"; } diff -Naurd mpfr-3.1.2-a/tests/tdiv.c mpfr-3.1.2-b/tests/tdiv.c --- mpfr-3.1.2-a/tests/tdiv.c 2013-03-13 15:37:44.000000000 +0000 +++ mpfr-3.1.2-b/tests/tdiv.c 2014-06-30 15:15:25.585268312 +0000 @@ -1104,6 +1104,96 @@ #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) #include "tgeneric.c" +static void +test_extreme (void) +{ + mpfr_t x, y, z; + mpfr_exp_t emin, emax; + mpfr_prec_t p[4] = { 8, 32, 64, 256 }; + int xi, yi, zi, j, r; + unsigned int flags, ex_flags; + + emin = mpfr_get_emin (); + emax = mpfr_get_emax (); + + mpfr_set_emin (MPFR_EMIN_MIN); + mpfr_set_emax (MPFR_EMAX_MAX); + + for (xi = 0; xi < 4; xi++) + { + mpfr_init2 (x, p[xi]); + mpfr_setmax (x, MPFR_EMAX_MAX); + MPFR_ASSERTN (mpfr_check (x)); + for (yi = 0; yi < 4; yi++) + { + mpfr_init2 (y, p[yi]); + mpfr_setmin (y, MPFR_EMIN_MIN); + for (j = 0; j < 2; j++) + { + MPFR_ASSERTN (mpfr_check (y)); + for (zi = 0; zi < 4; zi++) + { + mpfr_init2 (z, p[zi]); + RND_LOOP (r) + { + mpfr_clear_flags (); + mpfr_div (z, x, y, (mpfr_rnd_t) r); + flags = __gmpfr_flags; + MPFR_ASSERTN (mpfr_check (z)); + ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("Bad flags in test_extreme on z = a/b" + " with %s and\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("a = "); + mpfr_dump (x); + printf ("b = "); + mpfr_dump (y); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + printf ("z = "); + mpfr_dump (z); + exit (1); + } + mpfr_clear_flags (); + mpfr_div (z, y, x, (mpfr_rnd_t) r); + flags = __gmpfr_flags; + MPFR_ASSERTN (mpfr_check (z)); + ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; + if (flags != ex_flags) + { + printf ("Bad flags in test_extreme on z = a/b" + " with %s and\n", + mpfr_print_rnd_mode ((mpfr_rnd_t) r)); + printf ("a = "); + mpfr_dump (y); + printf ("b = "); + mpfr_dump (x); + printf ("Expected flags:"); + flags_out (ex_flags); + printf ("Got flags: "); + flags_out (flags); + printf ("z = "); + mpfr_dump (z); + exit (1); + } + } + mpfr_clear (z); + } /* zi */ + mpfr_nextabove (y); + } /* j */ + mpfr_clear (y); + } /* yi */ + mpfr_clear (x); + } /* xi */ + + set_emin (emin); + set_emax (emax); +} + int main (int argc, char *argv[]) { @@ -1130,6 +1220,7 @@ test_20070603 (); test_20070628 (); test_generic (2, 800, 50); + test_extreme (); tests_end_mpfr (); return 0;