blob: 6ff7c4ac92e734dce54edf4148c0509836241471 [file] [log] [blame]
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;