| 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; |