Date: Monday, September 12, 2016 @ 01:49:52 Author: allan Revision: 276183
upgpkg: mpfr 3.1.4.p5-1 upstream bugfix patch bump Added: mpfr/trunk/mpfr-3.1.4-p5.patch Modified: mpfr/trunk/PKGBUILD Deleted: mpfr/trunk/mpfr-3.1.4-p1.patch ---------------------+ PKGBUILD | 4 mpfr-3.1.4-p1.patch | 56 -- mpfr-3.1.4-p5.patch | 1091 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1093 insertions(+), 58 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2016-09-12 01:31:03 UTC (rev 276182) +++ PKGBUILD 2016-09-12 01:49:52 UTC (rev 276183) @@ -4,7 +4,7 @@ pkgname=mpfr _pkgver=3.1.4 -_patchlevel=p1 +_patchlevel=p5 pkgver=${_pkgver}.${_patchlevel} #pkgver=${_pkgver} pkgrel=1 @@ -17,7 +17,7 @@ mpfr-${_pkgver}-${_patchlevel}.patch) md5sums=('064b2c18185038e404a401b830d59be8' 'SKIP' - '450ac9de7e6d99b05ffd4ba063c77382') + '2563d5dfd3bb78fed389d03ec902fcea') validpgpkeys=('07F3DBBECC1A39605078094D980C197698C3739D') prepare() { Deleted: mpfr-3.1.4-p1.patch =================================================================== --- mpfr-3.1.4-p1.patch 2016-09-12 01:31:03 UTC (rev 276182) +++ mpfr-3.1.4-p1.patch 2016-09-12 01:49:52 UTC (rev 276183) @@ -1,56 +0,0 @@ -diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES ---- mpfr-3.1.4-a/PATCHES 2016-04-13 21:22:23.720604013 +0000 -+++ mpfr-3.1.4-b/PATCHES 2016-04-13 21:22:23.744603677 +0000 -@@ -0,0 +1 @@ -+unix-check -diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION ---- mpfr-3.1.4-a/VERSION 2016-03-06 11:33:04.000000000 +0000 -+++ mpfr-3.1.4-b/VERSION 2016-04-13 21:22:23.744603677 +0000 -@@ -1 +1 @@ --3.1.4 -+3.1.4-p1 -diff -Naurd mpfr-3.1.4-a/src/mpfr-impl.h mpfr-3.1.4-b/src/mpfr-impl.h ---- mpfr-3.1.4-a/src/mpfr-impl.h 2016-03-06 11:33:04.000000000 +0000 -+++ mpfr-3.1.4-b/src/mpfr-impl.h 2016-04-13 21:22:23.736603789 +0000 -@@ -252,19 +252,6 @@ - # define MPFR_WIN_THREAD_SAFE_DLL 1 - #endif - --/* Detect some possible inconsistencies under Unix. */ --#if defined(__unix__) --# if defined(_WIN32) --# error "Both __unix__ and _WIN32 are defined" --# endif --# if __GMP_LIBGMP_DLL --# error "__unix__ is defined and __GMP_LIBGMP_DLL is true" --# endif --# if defined(MPFR_WIN_THREAD_SAFE_DLL) --# error "Both __unix__ and MPFR_WIN_THREAD_SAFE_DLL are defined" --# endif --#endif -- - #if defined(__MPFR_WITHIN_MPFR) || !defined(MPFR_WIN_THREAD_SAFE_DLL) - extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags; - extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin; -diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h ---- mpfr-3.1.4-a/src/mpfr.h 2016-03-06 11:33:04.000000000 +0000 -+++ mpfr-3.1.4-b/src/mpfr.h 2016-04-13 21:22:23.744603677 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 1 - #define MPFR_VERSION_PATCHLEVEL 4 --#define MPFR_VERSION_STRING "3.1.4" -+#define MPFR_VERSION_STRING "3.1.4-p1" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c ---- mpfr-3.1.4-a/src/version.c 2016-03-06 11:33:05.000000000 +0000 -+++ mpfr-3.1.4-b/src/version.c 2016-04-13 21:22:23.744603677 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.1.4"; -+ return "3.1.4-p1"; - } Added: mpfr-3.1.4-p5.patch =================================================================== --- mpfr-3.1.4-p5.patch (rev 0) +++ mpfr-3.1.4-p5.patch 2016-09-12 01:49:52 UTC (rev 276183) @@ -0,0 +1,1091 @@ +diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES +--- mpfr-3.1.4-a/PATCHES 2016-04-13 21:22:23.720604013 +0000 ++++ mpfr-3.1.4-b/PATCHES 2016-04-13 21:22:23.744603677 +0000 +@@ -0,0 +1 @@ ++unix-check +diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION +--- mpfr-3.1.4-a/VERSION 2016-03-06 11:33:04.000000000 +0000 ++++ mpfr-3.1.4-b/VERSION 2016-04-13 21:22:23.744603677 +0000 +@@ -1 +1 @@ +-3.1.4 ++3.1.4-p1 +diff -Naurd mpfr-3.1.4-a/src/mpfr-impl.h mpfr-3.1.4-b/src/mpfr-impl.h +--- mpfr-3.1.4-a/src/mpfr-impl.h 2016-03-06 11:33:04.000000000 +0000 ++++ mpfr-3.1.4-b/src/mpfr-impl.h 2016-04-13 21:22:23.736603789 +0000 +@@ -252,19 +252,6 @@ + # define MPFR_WIN_THREAD_SAFE_DLL 1 + #endif + +-/* Detect some possible inconsistencies under Unix. */ +-#if defined(__unix__) +-# if defined(_WIN32) +-# error "Both __unix__ and _WIN32 are defined" +-# endif +-# if __GMP_LIBGMP_DLL +-# error "__unix__ is defined and __GMP_LIBGMP_DLL is true" +-# endif +-# if defined(MPFR_WIN_THREAD_SAFE_DLL) +-# error "Both __unix__ and MPFR_WIN_THREAD_SAFE_DLL are defined" +-# endif +-#endif +- + #if defined(__MPFR_WITHIN_MPFR) || !defined(MPFR_WIN_THREAD_SAFE_DLL) + extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags; + extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin; +diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h +--- mpfr-3.1.4-a/src/mpfr.h 2016-03-06 11:33:04.000000000 +0000 ++++ mpfr-3.1.4-b/src/mpfr.h 2016-04-13 21:22:23.744603677 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 4 +-#define MPFR_VERSION_STRING "3.1.4" ++#define MPFR_VERSION_STRING "3.1.4-p1" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c +--- mpfr-3.1.4-a/src/version.c 2016-03-06 11:33:05.000000000 +0000 ++++ mpfr-3.1.4-b/src/version.c 2016-04-13 21:22:23.744603677 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.4"; ++ return "3.1.4-p1"; + } +diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES +--- mpfr-3.1.4-a/PATCHES 2016-05-22 19:59:43.838399677 +0000 ++++ mpfr-3.1.4-b/PATCHES 2016-05-22 19:59:43.866399168 +0000 +@@ -0,0 +1 @@ ++add-sub-ui-flags +diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION +--- mpfr-3.1.4-a/VERSION 2016-04-13 21:22:23.744603677 +0000 ++++ mpfr-3.1.4-b/VERSION 2016-05-22 19:59:43.866399168 +0000 +@@ -1 +1 @@ +-3.1.4-p1 ++3.1.4-p2 +diff -Naurd mpfr-3.1.4-a/src/add_ui.c mpfr-3.1.4-b/src/add_ui.c +--- mpfr-3.1.4-a/src/add_ui.c 2016-03-06 11:33:04.000000000 +0000 ++++ mpfr-3.1.4-b/src/add_ui.c 2016-05-22 19:59:43.854399385 +0000 +@@ -49,6 +49,7 @@ + MPFR_SAVE_EXPO_MARK (expo); + MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt); + inex = mpfr_add(y, x, uu, rnd_mode); ++ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_check_range(y, inex, rnd_mode); + } +diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h +--- mpfr-3.1.4-a/src/mpfr.h 2016-04-13 21:22:23.744603677 +0000 ++++ mpfr-3.1.4-b/src/mpfr.h 2016-05-22 19:59:43.862399241 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 4 +-#define MPFR_VERSION_STRING "3.1.4-p1" ++#define MPFR_VERSION_STRING "3.1.4-p2" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.4-a/src/sub_ui.c mpfr-3.1.4-b/src/sub_ui.c +--- mpfr-3.1.4-a/src/sub_ui.c 2016-03-06 11:33:05.000000000 +0000 ++++ mpfr-3.1.4-b/src/sub_ui.c 2016-05-22 19:59:43.854399385 +0000 +@@ -52,6 +52,7 @@ + MPFR_SAVE_EXPO_MARK (expo); + MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt); + inex = mpfr_sub (y, x, uu, rnd_mode); ++ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_check_range (y, inex, rnd_mode); + } +diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c +--- mpfr-3.1.4-a/src/version.c 2016-04-13 21:22:23.744603677 +0000 ++++ mpfr-3.1.4-b/src/version.c 2016-05-22 19:59:43.866399168 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.4-p1"; ++ return "3.1.4-p2"; + } +diff -Naurd mpfr-3.1.4-a/tests/tadd_ui.c mpfr-3.1.4-b/tests/tadd_ui.c +--- mpfr-3.1.4-a/tests/tadd_ui.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tadd_ui.c 2016-05-22 19:59:43.854399385 +0000 +@@ -69,7 +69,9 @@ + + /* nan + 2394875 == nan */ + mpfr_set_nan (x); ++ mpfr_clear_nanflag (); + mpfr_add_ui (y, x, 2394875L, MPFR_RNDN); ++ MPFR_ASSERTN (mpfr_nanflag_p ()); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf + 2394875 == +inf */ +diff -Naurd mpfr-3.1.4-a/tests/tsub_ui.c mpfr-3.1.4-b/tests/tsub_ui.c +--- mpfr-3.1.4-a/tests/tsub_ui.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tsub_ui.c 2016-05-22 19:59:43.854399385 +0000 +@@ -96,7 +96,9 @@ + + /* nan - 1 == nan */ + mpfr_set_nan (x); ++ mpfr_clear_nanflag (); + mpfr_sub_ui (y, x, 1L, MPFR_RNDN); ++ MPFR_ASSERTN (mpfr_nanflag_p ()); + MPFR_ASSERTN (mpfr_nan_p (y)); + + /* +inf - 1 == +inf */ +diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES +--- mpfr-3.1.4-a/PATCHES 2016-06-01 13:00:30.748711490 +0000 ++++ mpfr-3.1.4-b/PATCHES 2016-06-01 13:00:30.772711162 +0000 +@@ -0,0 +1 @@ ++sub1-overflow +diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION +--- mpfr-3.1.4-a/VERSION 2016-05-22 19:59:43.866399168 +0000 ++++ mpfr-3.1.4-b/VERSION 2016-06-01 13:00:30.772711162 +0000 +@@ -1 +1 @@ +-3.1.4-p2 ++3.1.4-p3 +diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h +--- mpfr-3.1.4-a/src/mpfr.h 2016-05-22 19:59:43.862399241 +0000 ++++ mpfr-3.1.4-b/src/mpfr.h 2016-06-01 13:00:30.772711162 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 4 +-#define MPFR_VERSION_STRING "3.1.4-p2" ++#define MPFR_VERSION_STRING "3.1.4-p3" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.4-a/src/sub1.c mpfr-3.1.4-b/src/sub1.c +--- mpfr-3.1.4-a/src/sub1.c 2016-03-06 11:33:05.000000000 +0000 ++++ mpfr-3.1.4-b/src/sub1.c 2016-06-01 13:00:30.760711326 +0000 +@@ -96,16 +96,15 @@ + /* A = S*ABS(B) +/- ulp(a) */ + MPFR_SET_EXP (a, MPFR_GET_EXP (b)); + MPFR_RNDRAW_EVEN (inexact, a, MPFR_MANT (b), MPFR_PREC (b), +- rnd_mode, MPFR_SIGN (a), +- if (MPFR_UNLIKELY ( ++MPFR_EXP (a) > __gmpfr_emax)) +- inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a))); +- /* inexact = mpfr_set4 (a, b, rnd_mode, MPFR_SIGN (a)); */ ++ rnd_mode, MPFR_SIGN (a), ++ MPFR_EXP (a)); + if (inexact == 0) + { + /* a = b (Exact) + But we know it isn't (Since we have to remove `c') + So if we round to Zero, we have to remove one ulp. + Otherwise the result is correctly rounded. */ ++ /* An overflow is not possible. */ ++ MPFR_ASSERTD (MPFR_EXP (a) <= __gmpfr_emax); + if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (a))) + { + mpfr_nexttozero (a); +@@ -136,9 +135,14 @@ + i.e. inexact= MPFR_EVEN_INEX */ + if (MPFR_UNLIKELY (inexact == MPFR_EVEN_INEX*MPFR_INT_SIGN (a))) + { +- mpfr_nexttozero (a); ++ if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax)) ++ mpfr_setmax (a, __gmpfr_emax); ++ else ++ mpfr_nexttozero (a); + inexact = -MPFR_INT_SIGN (a); + } ++ else if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax)) ++ inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a)); + MPFR_RET (inexact); + } + } +diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c +--- mpfr-3.1.4-a/src/version.c 2016-05-22 19:59:43.866399168 +0000 ++++ mpfr-3.1.4-b/src/version.c 2016-06-01 13:00:30.772711162 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.4-p2"; ++ return "3.1.4-p3"; + } +diff -Naurd mpfr-3.1.4-a/tests/tsub.c mpfr-3.1.4-b/tests/tsub.c +--- mpfr-3.1.4-a/tests/tsub.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tsub.c 2016-06-01 13:00:30.760711326 +0000 +@@ -630,6 +630,135 @@ + } + } + ++static void ++check_max_almosteven (void) ++{ ++ mpfr_exp_t old_emin, old_emax; ++ mpfr_exp_t emin[2] = { MPFR_EMIN_MIN, -1000 }; ++ mpfr_exp_t emax[2] = { MPFR_EMAX_MAX, 1000 }; ++ int i; ++ ++ old_emin = mpfr_get_emin (); ++ old_emax = mpfr_get_emax (); ++ ++ for (i = 0; i < 2; i++) ++ { ++ mpfr_t a1, a2, b, c; ++ mpfr_prec_t p; ++ int neg, j, rnd; ++ ++ set_emin (emin[i]); ++ set_emax (emax[i]); ++ ++ p = MPFR_PREC_MIN + randlimb () % 70; ++ mpfr_init2 (a1, p); ++ mpfr_init2 (a2, p); ++ mpfr_init2 (b, p+1); ++ mpfr_init2 (c, MPFR_PREC_MIN); ++ ++ mpfr_setmax (b, 0); ++ mpfr_set_ui (c, 1, MPFR_RNDN); ++ ++ for (neg = 0; neg < 2; neg++) ++ { ++ for (j = 1; j >= 0; j--) ++ { ++ mpfr_set_exp (b, __gmpfr_emax - j); ++ RND_LOOP (rnd) ++ { ++ unsigned int flags1, flags2; ++ int inex1, inex2; ++ ++ flags1 = MPFR_FLAGS_INEXACT; ++ if (rnd == MPFR_RNDN || MPFR_IS_LIKE_RNDZ (rnd, neg)) ++ { ++ inex1 = neg ? 1 : -1; ++ mpfr_setmax (a1, __gmpfr_emax - j); ++ } ++ else ++ { ++ inex1 = neg ? -1 : 1; ++ if (j == 0) ++ { ++ flags1 |= MPFR_FLAGS_OVERFLOW; ++ mpfr_set_inf (a1, 1); ++ } ++ else ++ { ++ mpfr_setmin (a1, __gmpfr_emax); ++ } ++ } ++ MPFR_SET_SIGN (a1, neg ? -1 : 1); ++ ++ mpfr_clear_flags (); ++ inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd); ++ flags2 = __gmpfr_flags; ++ ++ if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) && ++ mpfr_equal_p (a1, a2))) ++ { ++ printf ("Error 1 in check_max_almosteven for %s," ++ " i = %d, j = %d, neg = %d\n", ++ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), ++ i, j, neg); ++ printf (" b = "); ++ mpfr_dump (b); ++ printf ("Expected "); ++ mpfr_dump (a1); ++ printf (" with inex = %d, flags =", inex1); ++ flags_out (flags1); ++ printf ("Got "); ++ mpfr_dump (a2); ++ printf (" with inex = %d, flags =", inex2); ++ flags_out (flags2); ++ exit (1); ++ } ++ ++ if (i == 0) ++ break; ++ ++ mpfr_clear_flags (); ++ set_emin (MPFR_EMIN_MIN); ++ set_emax (MPFR_EMAX_MAX); ++ inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd); ++ set_emin (emin[i]); ++ set_emax (emax[i]); ++ inex2 = mpfr_check_range (a2, inex2, (mpfr_rnd_t) rnd); ++ flags2 = __gmpfr_flags; ++ ++ if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) && ++ mpfr_equal_p (a1, a2))) ++ { ++ printf ("Error 2 in check_max_almosteven for %s," ++ " i = %d, j = %d, neg = %d\n", ++ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), ++ i, j, neg); ++ printf (" b = "); ++ mpfr_dump (b); ++ printf ("Expected "); ++ mpfr_dump (a1); ++ printf (" with inex = %d, flags =", inex1); ++ flags_out (flags1); ++ printf ("Got "); ++ mpfr_dump (a2); ++ printf (" with inex = %d, flags =", inex2); ++ flags_out (flags2); ++ exit (1); ++ } ++ } ++ } /* j */ ++ ++ mpfr_neg (b, b, MPFR_RNDN); ++ mpfr_neg (c, c, MPFR_RNDN); ++ } /* neg */ ++ ++ mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0); ++ } /* i */ ++ ++ set_emin (old_emin); ++ set_emax (old_emax); ++} ++ + #define TEST_FUNCTION test_sub + #define TWO_ARGS + #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +@@ -647,6 +776,7 @@ + check_rounding (); + check_diverse (); + check_inexact (); ++ check_max_almosteven (); + bug_ddefour (); + for (p=2; p<200; p++) + for (i=0; i<50; i++) +diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES +--- mpfr-3.1.4-a/PATCHES 2016-08-04 20:41:14.097592781 +0000 ++++ mpfr-3.1.4-b/PATCHES 2016-08-04 20:41:14.121592350 +0000 +@@ -0,0 +1 @@ ++c++11-compat +diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION +--- mpfr-3.1.4-a/VERSION 2016-06-01 13:00:30.772711162 +0000 ++++ mpfr-3.1.4-b/VERSION 2016-08-04 20:41:14.121592350 +0000 +@@ -1 +1 @@ +-3.1.4-p3 ++3.1.4-p4 +diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h +--- mpfr-3.1.4-a/src/mpfr.h 2016-06-01 13:00:30.772711162 +0000 ++++ mpfr-3.1.4-b/src/mpfr.h 2016-08-04 20:41:14.121592350 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 4 +-#define MPFR_VERSION_STRING "3.1.4-p3" ++#define MPFR_VERSION_STRING "3.1.4-p4" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c +--- mpfr-3.1.4-a/src/version.c 2016-06-01 13:00:30.772711162 +0000 ++++ mpfr-3.1.4-b/src/version.c 2016-08-04 20:41:14.121592350 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.4-p3"; ++ return "3.1.4-p4"; + } +diff -Naurd mpfr-3.1.4-a/tests/tpow_z.c mpfr-3.1.4-b/tests/tpow_z.c +--- mpfr-3.1.4-a/tests/tpow_z.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tpow_z.c 2016-08-04 20:41:14.113592494 +0000 +@@ -26,7 +26,7 @@ + + #include "mpfr-test.h" + +-#define ERROR(str) do { printf("Error for "str"\n"); exit (1); } while (0) ++#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) + + static void + check_special (void) +diff -Naurd mpfr-3.1.4-a/tests/tset_si.c mpfr-3.1.4-b/tests/tset_si.c +--- mpfr-3.1.4-a/tests/tset_si.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tset_si.c 2016-08-04 20:41:14.113592494 +0000 +@@ -26,7 +26,7 @@ + + #include "mpfr-test.h" + +-#define ERROR(str) {printf("Error for "str"\n"); exit(1);} ++#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) + + static void + test_2exp (void) +diff -Naurd mpfr-3.1.4-a/tests/tset_sj.c mpfr-3.1.4-b/tests/tset_sj.c +--- mpfr-3.1.4-a/tests/tset_sj.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tset_sj.c 2016-08-04 20:41:14.113592494 +0000 +@@ -42,7 +42,7 @@ + + #else + +-#define ERROR(str) {printf("Error for "str"\n"); exit(1);} ++#define ERROR(str) do { printf ("Error for " str "\n"); exit (1); } while (0) + + static int + inexact_sign (int x) +diff -Naurd mpfr-3.1.4-a/tests/tsi_op.c mpfr-3.1.4-b/tests/tsi_op.c +--- mpfr-3.1.4-a/tests/tsi_op.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tsi_op.c 2016-08-04 20:41:14.113592494 +0000 +@@ -26,14 +26,16 @@ + + #include "mpfr-test.h" + +-#define ERROR1(s, i, z, exp) \ +-{\ +- printf("Error for "s" and i=%d\n", i);\ +- printf("Expected %s\n", exp);\ +- printf("Got "); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);\ +- putchar ('\n');\ +- exit(1);\ +-} ++#define ERROR1(s,i,z,exp) \ ++ do \ ++ { \ ++ printf ("Error for " s " and i=%d\n", i); \ ++ printf ("Expected %s\n", exp); \ ++ printf ("Got "); mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); \ ++ putchar ('\n'); \ ++ exit(1); \ ++ } \ ++ while (0) + + const struct { + const char * op1; +diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES +--- mpfr-3.1.4-a/PATCHES 2016-09-05 13:38:17.033213942 +0000 ++++ mpfr-3.1.4-b/PATCHES 2016-09-05 13:38:17.105214559 +0000 +@@ -0,0 +1 @@ ++can_round2 +diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION +--- mpfr-3.1.4-a/VERSION 2016-08-04 20:41:14.121592350 +0000 ++++ mpfr-3.1.4-b/VERSION 2016-09-05 13:38:17.105214559 +0000 +@@ -1 +1 @@ +-3.1.4-p4 ++3.1.4-p5 +diff -Naurd mpfr-3.1.4-a/src/mpfr-impl.h mpfr-3.1.4-b/src/mpfr-impl.h +--- mpfr-3.1.4-a/src/mpfr-impl.h 2016-04-13 21:22:23.736603789 +0000 ++++ mpfr-3.1.4-b/src/mpfr-impl.h 2016-09-05 13:38:17.077214319 +0000 +@@ -1885,6 +1885,7 @@ + __MPFR_DECLSPEC int mpfr_exp_2 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t)); + __MPFR_DECLSPEC int mpfr_exp_3 _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr,mpfr_rnd_t)); + __MPFR_DECLSPEC int mpfr_powerof2_raw _MPFR_PROTO ((mpfr_srcptr)); ++__MPFR_DECLSPEC int mpfr_powerof2_raw2 (const mp_limb_t *, mp_size_t); + + __MPFR_DECLSPEC int mpfr_pow_general _MPFR_PROTO ((mpfr_ptr, mpfr_srcptr, + mpfr_srcptr, mpfr_rnd_t, int, mpfr_save_expo_t *)); +diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h +--- mpfr-3.1.4-a/src/mpfr.h 2016-08-04 20:41:14.121592350 +0000 ++++ mpfr-3.1.4-b/src/mpfr.h 2016-09-05 13:38:17.101214525 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 4 +-#define MPFR_VERSION_STRING "3.1.4-p4" ++#define MPFR_VERSION_STRING "3.1.4-p5" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.4-a/src/powerof2.c mpfr-3.1.4-b/src/powerof2.c +--- mpfr-3.1.4-a/src/powerof2.c 2016-03-06 11:33:05.000000000 +0000 ++++ mpfr-3.1.4-b/src/powerof2.c 2016-09-05 13:38:17.077214319 +0000 +@@ -31,16 +31,17 @@ + int + mpfr_powerof2_raw (mpfr_srcptr x) + { +- mp_limb_t *xp; +- mp_size_t xn; +- + /* This is an internal function, and we may call it with some + wrong numbers (ie good mantissa but wrong flags or exp) + So we don't want to test if it is a pure FP. + MPFR_ASSERTN(MPFR_IS_PURE_FP(x)); */ +- xp = MPFR_MANT(x); +- xn = (MPFR_PREC(x) - 1) / GMP_NUMB_BITS; +- if (xp[xn] != MPFR_LIMB_HIGHBIT) ++ return mpfr_powerof2_raw2 (MPFR_MANT(x), MPFR_LIMB_SIZE(x)); ++} ++ ++int ++mpfr_powerof2_raw2 (const mp_limb_t *xp, mp_size_t xn) ++{ ++ if (xp[--xn] != MPFR_LIMB_HIGHBIT) + return 0; + while (xn > 0) + if (xp[--xn] != 0) +diff -Naurd mpfr-3.1.4-a/src/round_p.c mpfr-3.1.4-b/src/round_p.c +--- mpfr-3.1.4-a/src/round_p.c 2016-03-06 11:33:05.000000000 +0000 ++++ mpfr-3.1.4-b/src/round_p.c 2016-09-05 13:38:17.077214319 +0000 +@@ -35,10 +35,16 @@ + + i1 = mpfr_round_p_2 (bp, bn, err0, prec); + +- /* compare with mpfr_can_round_raw */ ++ /* Note: since revision 10747, mpfr_can_round_raw is supposed to be always ++ correct, whereas mpfr_round_p_2 might return 0 in some cases where one ++ could round, for example with err0=67 and prec=54: ++ b = 1111101101010001100011111011100010100011101111011011101111111111 ++ thus we cannot compare i1 and i2, we only can check that we don't have ++ i1 <> 0 and i2 = 0. ++ */ + i2 = mpfr_can_round_raw (bp, bn, MPFR_SIGN_POS, err0, + MPFR_RNDN, MPFR_RNDZ, prec); +- if (i1 != i2) ++ if (i1 && (i2 == 0)) + { + fprintf (stderr, "mpfr_round_p(%d) != mpfr_can_round(%d)!\n" + "bn = %lu, err0 = %ld, prec = %lu\nbp = ", i1, i2, +diff -Naurd mpfr-3.1.4-a/src/round_prec.c mpfr-3.1.4-b/src/round_prec.c +--- mpfr-3.1.4-a/src/round_prec.c 2016-03-06 11:33:04.000000000 +0000 ++++ mpfr-3.1.4-b/src/round_prec.c 2016-09-05 13:38:17.077214319 +0000 +@@ -138,47 +138,173 @@ + } + + int +-mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err0, ++mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err, + mpfr_rnd_t rnd1, mpfr_rnd_t rnd2, mpfr_prec_t prec) + { +- mpfr_prec_t err, prec0 = prec; ++ mpfr_prec_t prec2; + mp_size_t k, k1, tn; + int s, s1; + mp_limb_t cc, cc2; + mp_limb_t *tmp; ++ mp_limb_t cy = 0, tmp_hi; ++ int res; + MPFR_TMP_DECL(marker); + +- MPFR_ASSERTD(bp[bn - 1] & MPFR_LIMB_HIGHBIT); ++ /* Since mpfr_can_round is a function in the API, use MPFR_ASSERTN. ++ The specification makes sense only for prec >= 1. */ ++ MPFR_ASSERTN (prec >= 1); + +- if (MPFR_UNLIKELY(err0 < 0 || (mpfr_uexp_t) err0 <= prec)) +- return 0; /* can't round */ ++ MPFR_ASSERTD(bp[bn - 1] & MPFR_LIMB_HIGHBIT); + + MPFR_ASSERT_SIGN(neg); + neg = MPFR_IS_NEG_SIGN(neg); + + /* Transform RNDD and RNDU to Zero / Away */ +- MPFR_ASSERTD((neg == 0) || (neg == 1)); ++ MPFR_ASSERTD (neg == 0 || neg == 1); + if (rnd1 != MPFR_RNDN) + rnd1 = MPFR_IS_LIKE_RNDZ(rnd1, neg) ? MPFR_RNDZ : MPFR_RNDA; + if (rnd2 != MPFR_RNDN) + rnd2 = MPFR_IS_LIKE_RNDZ(rnd2, neg) ? MPFR_RNDZ : MPFR_RNDA; + ++ /* For err < prec (+1 for rnd1=RNDN), we can never round correctly, since ++ the error is at least 2*ulp(b) >= ulp(round(b)). ++ However for err = prec (+1 for rnd1=RNDN), we can round correctly in some ++ rare cases where ulp(b) = 1/2*ulp(U) [see below for the definition of U], ++ which implies rnd1 = RNDZ or RNDN, and rnd2 = RNDA or RNDN. */ ++ ++ if (MPFR_UNLIKELY (err < prec + (rnd1 == MPFR_RNDN) || ++ (err == prec + (rnd1 == MPFR_RNDN) && ++ (rnd1 == MPFR_RNDA || ++ rnd2 == MPFR_RNDZ)))) ++ return 0; /* can't round */ ++ ++ /* As a consequence... */ ++ MPFR_ASSERTD (err >= prec); ++ ++ /* The bound c on the error |x-b| is: c = 2^(MPFR_EXP(b)-err) <= b/2. ++ * So, we now know that x and b have the same sign. By symmetry, ++ * assume x > 0 and b > 0. We have: L <= x <= U, where, depending ++ * on rnd1: ++ * MPFR_RNDN: L = b-c, U = b+c ++ * MPFR_RNDZ: L = b, U = b+c ++ * MPFR_RNDA: L = b-c, U = b ++ * ++ * We can round x iff round(L,prec,rnd2) = round(U,prec,rnd2). ++ */ ++ + if (MPFR_UNLIKELY (prec > (mpfr_prec_t) bn * GMP_NUMB_BITS)) +- { /* Then prec < PREC(b): we can round: +- (i) in rounding to the nearest iff err0 >= prec + 2 ++ { /* Then prec > PREC(b): we can round: ++ (i) in rounding to the nearest as long as err >= prec + 2. ++ When err = prec + 1 and b is not a power ++ of two (so that a change of binade cannot occur), then one ++ can round to nearest thanks to the even rounding rule (in the ++ target precision prec, the significand of b ends with a 0). ++ When err = prec + 1 and b is a power of two, when rnd1 = RNDZ one ++ can round too. + (ii) in directed rounding mode iff rnd1 is compatible with rnd2 +- and err0 >= prec + 1, unless b = 2^k and rnd1=rnd2=RNDA in +- which case we need err0 >= prec + 2. */ ++ and err >= prec + 1, unless b = 2^k and rnd1 = RNDA or RNDN in ++ which case we need err >= prec + 2. ++ */ ++ if ((rnd1 == rnd2 || rnd2 == MPFR_RNDN) && err >= prec + 1) ++ { ++ if (rnd1 != MPFR_RNDZ && ++ err == prec + 1 && ++ mpfr_powerof2_raw2 (bp, bn)) ++ return 0; ++ else ++ return 1; ++ } ++ return 0; ++ } ++ ++ /* now prec <= bn * GMP_NUMB_BITS */ ++ ++ if (MPFR_UNLIKELY (err > (mpfr_prec_t) bn * GMP_NUMB_BITS)) ++ { ++ /* we distinguish the case where b is a power of two: ++ rnd1 rnd2 can round? ++ RNDZ RNDZ ok ++ RNDZ RNDA no ++ RNDZ RNDN ok ++ RNDA RNDZ no ++ RNDA RNDA ok except when err = prec + 1 ++ RNDA RNDN ok except when err = prec + 1 ++ RNDN RNDZ no ++ RNDN RNDA no ++ RNDN RNDN ok except when err = prec + 1 */ ++ if (mpfr_powerof2_raw2 (bp, bn)) ++ { ++ if ((rnd2 == MPFR_RNDZ || rnd2 == MPFR_RNDA) && rnd1 != rnd2) ++ return 0; ++ else if (rnd1 == MPFR_RNDZ) ++ return 1; /* RNDZ RNDZ and RNDZ RNDN */ ++ else ++ return err > prec + 1; ++ } ++ ++ /* now the general case where b is not a power of two: ++ rnd1 rnd2 can round? ++ RNDZ RNDZ ok ++ RNDZ RNDA except when b is representable in precision 'prec' ++ RNDZ RNDN except when b is the middle of two representable numbers in ++ precision 'prec' and b ends with 'xxx0[1]', ++ or b is representable in precision 'prec' ++ and err = prec + 1 and b ends with '1'. ++ RNDA RNDZ except when b is representable in precision 'prec' ++ RNDA RNDA ok ++ RNDA RNDN except when b is the middle of two representable numbers in ++ precision 'prec' and b ends with 'xxx1[1]', ++ or b is representable in precision 'prec' ++ and err = prec + 1 and b ends with '1'. ++ RNDN RNDZ except when b is representable in precision 'prec' ++ RNDN RNDA except when b is representable in precision 'prec' ++ RNDN RNDN except when b is the middle of two representable numbers in ++ precision 'prec', or b is representable in precision 'prec' ++ and err = prec + 1 and b ends with '1'. */ + if (rnd2 == MPFR_RNDN) +- return (mpfr_uexp_t) err0 - 2 >= prec; ++ { ++ if (err == prec + 1 && (bp[0] & 1)) ++ return 0; /* err == prec + 1 implies prec = bn * GMP_NUMB_BITS */ ++ if (prec < (mpfr_prec_t) bn * GMP_NUMB_BITS) ++ { ++ k1 = MPFR_PREC2LIMBS (prec + 1); ++ MPFR_UNSIGNED_MINUS_MODULO(s1, prec + 1); ++ if (((bp[bn - k1] >> s1) & 1) && ++ mpfr_round_raw2 (bp, bn, neg, MPFR_RNDA, prec + 1) == 0) ++ { /* b is the middle of two representable numbers */ ++ if (rnd1 == MPFR_RNDN) ++ return 0; ++ k1 = MPFR_PREC2LIMBS (prec); ++ MPFR_UNSIGNED_MINUS_MODULO(s1, prec); ++ return (rnd1 == MPFR_RNDZ) ^ ++ (((bp[bn - k1] >> s1) & 1) == 0); ++ } ++ } ++ return 1; ++ } ++ else if (rnd1 == rnd2) ++ { ++ if (rnd1 == MPFR_RNDN && prec < (mpfr_prec_t) bn * GMP_NUMB_BITS) ++ { ++ /* then rnd2 = RNDN, and for prec = bn * GMP_NUMB_BITS we cannot ++ have b the middle of two representable numbers */ ++ k1 = MPFR_PREC2LIMBS (prec + 1); ++ MPFR_UNSIGNED_MINUS_MODULO(s1, prec + 1); ++ if (((bp[bn - k1] >> s1) & 1) && ++ mpfr_round_raw2 (bp, bn, neg, MPFR_RNDA, prec + 1) == 0) ++ /* b is representable in precision prec+1 and ends with a 1 */ ++ return 0; ++ else ++ return 1; ++ } ++ else ++ return 1; ++ } + else +- return (rnd1 == rnd2) && (mpfr_uexp_t) err0 - 2 >= prec; ++ return mpfr_round_raw2 (bp, bn, neg, MPFR_RNDA, prec) != 0; + } + +- /* if the error is smaller than ulp(b), then anyway it will propagate +- up to ulp(b) */ +- err = ((mpfr_uexp_t) err0 > (mpfr_prec_t) bn * GMP_NUMB_BITS) ? +- (mpfr_prec_t) bn * GMP_NUMB_BITS : (mpfr_prec_t) err0; ++ /* now err <= bn * GMP_NUMB_BITS */ + + /* warning: if k = m*GMP_NUMB_BITS, consider limb m-1 and not m */ + k = (err - 1) / GMP_NUMB_BITS; +@@ -196,7 +322,7 @@ + Warning! The number with updated bn may no longer be normalized. */ + k -= k1; + bn -= k1; +- prec -= (mpfr_prec_t) k1 * GMP_NUMB_BITS; ++ prec2 = prec - (mpfr_prec_t) k1 * GMP_NUMB_BITS; + + /* We can decide of the correct rounding if rnd2(b-eps) and rnd2(b+eps) + give the same result to the target precision 'prec', i.e., if when +@@ -215,64 +341,150 @@ + switch (rnd1) + { + case MPFR_RNDZ: +- /* Round to Zero */ ++ /* rnd1 = Round to Zero */ + cc = (bp[bn - 1] >> s1) & 1; + /* mpfr_round_raw2 returns 1 if one should add 1 at ulp(b,prec), + and 0 otherwise */ +- cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec); ++ cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec2); + /* cc is the new value of bit s1 in bp[bn-1] after rounding 'rnd2' */ + + /* now round b + 2^(MPFR_EXP(b)-err) */ +- mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); +- /* if there was a carry here, then necessarily bit s1 of bp[bn-1] +- changed, thus we surely cannot round for directed rounding, but this +- will be detected below, with cc2 != cc */ ++ cy = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); ++ /* propagate carry up to most significant limb */ ++ for (tn = 0; tn + 1 < k1 && cy != 0; tn ++) ++ cy = ~bp[bn + tn] == 0; ++ if (cy == 0 && err == prec) ++ { ++ res = 0; ++ goto end; ++ } ++ if (MPFR_UNLIKELY(cy)) ++ { ++ /* when a carry occurs, we have b < 2^h <= b+c, we can round iff: ++ rnd2 = RNDZ: never, since b and b+c round to different values; ++ rnd2 = RNDA: when b+c is an exact power of two, and err > prec ++ (since for err = prec, b = 2^h - 1/2*ulp(2^h) is ++ exactly representable and thus rounds to itself); ++ rnd2 = RNDN: whenever cc = 0, since err >= prec implies ++ c <= ulp(b) = 1/2*ulp(2^h), thus b+c rounds to 2^h, ++ and b+c >= 2^h implies that bit 'prec' of b is 1, ++ thus cc = 0 means that b is rounded to 2^h too. */ ++ res = (rnd2 == MPFR_RNDZ) ? 0 ++ : (rnd2 == MPFR_RNDA) ? (err > prec && k == bn && tmp[0] == 0) ++ : cc == 0; ++ goto end; ++ } + break; + case MPFR_RNDN: +- /* Round to nearest */ ++ /* rnd1 = Round to nearest */ + + /* first round b+2^(MPFR_EXP(b)-err) */ +- mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); +- /* same remark as above in case a carry occurs in mpn_add_1() */ ++ cy = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); ++ /* propagate carry up to most significant limb */ ++ for (tn = 0; tn + 1 < k1 && cy != 0; tn ++) ++ cy = ~bp[bn + tn] == 0; + cc = (tmp[bn - 1] >> s1) & 1; /* gives 0 when cc=1 */ +- cc ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec); ++ cc ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec2); + /* cc is the new value of bit s1 in bp[bn-1]+eps after rounding 'rnd2' */ +- ++ if (MPFR_UNLIKELY (cy != 0)) ++ { ++ /* when a carry occurs, we have b-c < b < 2^h <= b+c, we can round ++ iff: ++ rnd2 = RNDZ: never, since b-c and b+c round to different values; ++ rnd2 = RNDA: when b+c is an exact power of two, and ++ err > prec + 1 (since for err <= prec + 1, ++ b-c <= 2^h - 1/2*ulp(2^h) is exactly representable ++ and thus rounds to itself); ++ rnd2 = RNDN: whenever err > prec + 1, since for err = prec + 1, ++ b+c rounds to 2^h, and b-c rounds to nextbelow(2^h). ++ For err > prec + 1, c <= 1/4*ulp(b) <= 1/8*ulp(2^h), ++ thus ++ 2^h - 1/4*ulp(b) <= b-c < b+c <= 2^h + 1/8*ulp(2^h), ++ therefore both b-c and b+c round to 2^h. */ ++ res = (rnd2 == MPFR_RNDZ) ? 0 ++ : (rnd2 == MPFR_RNDA) ? (err > prec + 1 && k == bn && tmp[0] == 0) ++ : err > prec + 1; ++ goto end; ++ } + subtract_eps: +- /* now round b-2^(MPFR_EXP(b)-err) */ +- cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); ++ /* now round b-2^(MPFR_EXP(b)-err), this happens for ++ rnd1 = RNDN or RNDA */ ++ MPFR_ASSERTD(rnd1 == MPFR_RNDN || rnd1 == MPFR_RNDA); ++ cy = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s); + /* propagate the potential borrow up to the most significant limb + (it cannot propagate further since the most significant limb is +- at least MPFR_LIMB_HIGHBIT) */ +- for (tn = 0; tn + 1 < k1 && (cc2 != 0); tn ++) +- cc2 = bp[bn + tn] == 0; +- /* We have an exponent decrease when either: +- (i) k1 = 0 and tmp[bn-1] < MPFR_LIMB_HIGHBIT +- (ii) k1 > 0 and cc <> 0 and bp[bn + tn] = MPFR_LIMB_HIGHBIT +- (then necessarily tn = k1-1). +- Then for directed rounding we cannot round, +- and for rounding to nearest we cannot round when err = prec + 1. ++ at least MPFR_LIMB_HIGHBIT). ++ Note: we use the same limb tmp[bn-1] to subtract. */ ++ tmp_hi = tmp[bn - 1]; ++ for (tn = 0; tn < k1 && cy != 0; tn ++) ++ cy = mpn_sub_1 (&tmp_hi, bp + bn + tn, 1, cy); ++ /* We have an exponent decrease when tn = k1 and ++ tmp[bn-1] < MPFR_LIMB_HIGHBIT: ++ b-c < 2^h <= b (for RNDA) or b+c (for RNDN). ++ Then we surely cannot round when rnd2 = RNDZ, since b or b+c round to ++ a value >= 2^h, and b-c rounds to a value < 2^h. ++ We also surely cannot round when (rnd1,rnd2) = (RNDN,RNDA), since ++ b-c rounds to a value <= 2^h, and b+c > 2^h rounds to a value > 2^h. ++ It thus remains: ++ (rnd1,rnd2) = (RNDA,RNDA), (RNDA,RNDN) and (RNDN,RNDN). ++ For (RNDA,RNDA) we can round only when b-c and b round to 2^h, which ++ implies b = 2^h and err > prec (which is true in that case): ++ a necessary condition is that cc = 0. ++ For (RNDA,RNDN) we can round only when b-c and b round to 2^h, which ++ implies b-c >= 2^h - 1/4*ulp(2^h), and b <= 2^h + 1/2*ulp(2^h); ++ since ulp(2^h) = ulp(b), this implies c <= 3/4*ulp(b), thus ++ err > prec. ++ For (RNDN,RNDN) we can round only when b-c and b+c round to 2^h, ++ which implies b-c >= 2^h - 1/4*ulp(2^h), and ++ b+c <= 2^h + 1/2*ulp(2^h); ++ since ulp(2^h) = ulp(b), this implies 2*c <= 3/4*ulp(b), thus ++ err > prec+1. + */ +- if (((k1 == 0 && tmp[bn - 1] < MPFR_LIMB_HIGHBIT) || +- (k1 != 0 && cc2 != 0 && bp[bn + tn] == MPFR_LIMB_HIGHBIT)) && +- (rnd2 != MPFR_RNDN || err0 == prec0 + 1)) ++ if (tn == k1 && tmp_hi < MPFR_LIMB_HIGHBIT) /* exponent decrease */ + { +- MPFR_TMP_FREE(marker); +- return 0; ++ if (rnd2 == MPFR_RNDZ || (rnd1 == MPFR_RNDN && rnd2 == MPFR_RNDA) || ++ cc != 0 /* b or b+c does not round to 2^h */) ++ { ++ res = 0; ++ goto end; ++ } ++ /* in that case since the most significant bit of tmp is 0, we ++ should consider one more bit; res = 0 when b-c does not round ++ to 2^h. */ ++ res = mpfr_round_raw2 (tmp, bn, neg, rnd2, prec2 + 1) != 0; ++ goto end; ++ } ++ if (err == prec + (rnd1 == MPFR_RNDN)) ++ { ++ /* No exponent increase nor decrease, thus we have |U-L| = ulp(b). ++ For rnd2 = RNDZ or RNDA, either [L,U] contains one representable ++ number in the target precision, and then L and U round ++ differently; or both L and U are representable: they round ++ differently too; thus in all cases we cannot round. ++ For rnd2 = RNDN, the only case where we can round is when the ++ middle of [L,U] (i.e. b) is representable, and ends with a 0. */ ++ res = (rnd2 == MPFR_RNDN && (((bp[bn - 1] >> s1) & 1) == 0) && ++ mpfr_round_raw2 (bp, bn, neg, MPFR_RNDZ, prec2) == ++ mpfr_round_raw2 (bp, bn, neg, MPFR_RNDA, prec2)); ++ goto end; + } + break; + default: +- /* Round away */ ++ /* rnd1 = Round away */ ++ MPFR_ASSERTD (rnd1 == MPFR_RNDA); + cc = (bp[bn - 1] >> s1) & 1; +- cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec); ++ /* the mpfr_round_raw2() call below returns whether one should add 1 or ++ not for rounding */ ++ cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec2); + /* cc is the new value of bit s1 in bp[bn-1]+eps after rounding 'rnd2' */ + + goto subtract_eps; + } + + cc2 = (tmp[bn - 1] >> s1) & 1; +- cc2 ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec); ++ res = cc == (cc2 ^ mpfr_round_raw2 (tmp, bn, neg, rnd2, prec2)); + ++ end: + MPFR_TMP_FREE(marker); +- return cc == cc2; ++ return res; + } +diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c +--- mpfr-3.1.4-a/src/version.c 2016-08-04 20:41:14.121592350 +0000 ++++ mpfr-3.1.4-b/src/version.c 2016-09-05 13:38:17.101214525 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.4-p4"; ++ return "3.1.4-p5"; + } +diff -Naurd mpfr-3.1.4-a/tests/tcan_round.c mpfr-3.1.4-b/tests/tcan_round.c +--- mpfr-3.1.4-a/tests/tcan_round.c 2016-03-06 11:33:03.000000000 +0000 ++++ mpfr-3.1.4-b/tests/tcan_round.c 2016-09-05 13:38:17.077214319 +0000 +@@ -25,6 +25,44 @@ + + #include "mpfr-test.h" + ++/* Simple cases where err - prec is large enough. ++ One can get failures as a consequence of r9883. */ ++static void ++test_simple (void) ++{ ++ int t[4] = { 2, 3, -2, -3 }; /* test powers of 2 and non-powers of 2 */ ++ int i; ++ int r1, r2; ++ ++ for (i = 0; i < 4; i++) ++ RND_LOOP (r1) ++ RND_LOOP (r2) ++ { ++ mpfr_t b; ++ int p, err, prec, inex, c; ++ ++ p = 12 + (randlimb() % (2 * GMP_NUMB_BITS)); ++ err = p - 3; ++ prec = 4; ++ mpfr_init2 (b, p); ++ inex = mpfr_set_si (b, t[i], MPFR_RNDN); ++ MPFR_ASSERTN (inex == 0); ++ c = mpfr_can_round (b, err, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, prec); ++ /* If r1 == r2, we can round. ++ TODO: complete this test for r1 != r2. */ ++ if (r1 == r2 && !c) ++ { ++ printf ("Error in test_simple for i=%d," ++ " err=%d r1=%s, r2=%s, p=%d\n", i, err, ++ mpfr_print_rnd_mode ((mpfr_rnd_t) r1), ++ mpfr_print_rnd_mode ((mpfr_rnd_t) r2), p); ++ printf ("b="); mpfr_dump (b); ++ exit (1); ++ } ++ mpfr_clear (b); ++ } ++} ++ + #define MAX_LIMB_SIZE 100 + + static void +@@ -87,12 +125,7 @@ + MPFR_IS_LIKE_RNDU (r1, MPFR_SIGN_POS) ? + (MPFR_IS_LIKE_RNDD (r2, MPFR_SIGN_POS) ? 0 : prec < i) : + (r2 != MPFR_RNDN ? 0 : prec < i); +- /* We only require mpfr_can_round to return 1 when we can really +- round, it is allowed to return 0 in some rare boundary cases, +- for example when x = 2^k and the error is 0.25 ulp. +- Note: if this changes in the future, the test could be improved by +- removing the "&& expected_b == 0" below. */ +- if (b != expected_b && expected_b == 0) ++ if (b != expected_b) + { + printf ("Error for x=2^%d, px=%lu, err=%d, r1=%s, r2=%s, prec=%d\n", + (int) i, (unsigned long) px, (int) i + 1, +@@ -118,6 +151,80 @@ + mpfr_clear (x); + } + ++static void ++check_can_round (void) ++{ ++ mpfr_t x, xinf, xsup, yinf, ysup; ++ int precx, precy, err; ++ int rnd1, rnd2; ++ int i, u[3] = { 0, 1, 256 }; ++ int inex; ++ int expected, got; ++ ++ mpfr_inits2 (4 * GMP_NUMB_BITS, x, xinf, xsup, yinf, ysup, (mpfr_ptr) 0); ++ ++ for (precx = 3 * GMP_NUMB_BITS - 3; precx <= 3 * GMP_NUMB_BITS + 3; precx++) ++ { ++ mpfr_set_prec (x, precx); ++ for (precy = precx - 4; precy <= precx + 4; precy++) ++ { ++ mpfr_set_prec (yinf, precy); ++ mpfr_set_prec (ysup, precy); ++ ++ for (i = 0; i <= 3; i++) ++ { ++ if (i <= 2) ++ { ++ /* Test x = 2^(precx - 1) + u */ ++ mpfr_set_ui_2exp (x, 1, precx - 1, MPFR_RNDN); ++ mpfr_add_ui (x, x, u[i], MPFR_RNDN); ++ } ++ else ++ { ++ /* Test x = 2^precx - 1 */ ++ mpfr_set_ui_2exp (x, 1, precx, MPFR_RNDN); ++ mpfr_sub_ui (x, x, 1, MPFR_RNDN); ++ } ++ MPFR_ASSERTN (mpfr_get_exp (x) == precx); ++ ++ for (err = precy; err <= precy + 3; err++) ++ { ++ mpfr_set_ui_2exp (xinf, 1, precx - err, MPFR_RNDN); ++ inex = mpfr_add (xsup, x, xinf, MPFR_RNDN); ++ MPFR_ASSERTN (inex == 0); ++ inex = mpfr_sub (xinf, x, xinf, MPFR_RNDN); ++ MPFR_ASSERTN (inex == 0); ++ RND_LOOP (rnd1) ++ RND_LOOP (rnd2) ++ { ++ mpfr_set (yinf, MPFR_IS_LIKE_RNDD (rnd1, 1) ? ++ x : xinf, (mpfr_rnd_t) rnd2); ++ mpfr_set (ysup, MPFR_IS_LIKE_RNDU (rnd1, 1) ? ++ x : xsup, (mpfr_rnd_t) rnd2); ++ expected = !! mpfr_equal_p (yinf, ysup); ++ got = !! mpfr_can_round (x, err, (mpfr_rnd_t) rnd1, ++ (mpfr_rnd_t) rnd2, precy); ++ if (got != expected) ++ { ++ printf ("Error in check_can_round on:\n" ++ "precx=%d, precy=%d, i=%d, err=%d, " ++ "rnd1=%s, rnd2=%s: got %d\n", ++ precx, precy, i, err, ++ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd1), ++ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd2), ++ got); ++ printf ("x="); mpfr_dump (x); ++ exit (1); ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ mpfr_clears (x, xinf, xsup, yinf, ysup, (mpfr_ptr) 0); ++} ++ + int + main (void) + { +@@ -128,6 +235,8 @@ + + tests_start_mpfr (); + ++ test_simple (); ++ + /* checks that rounds to nearest sets the last + bit to zero in case of equal distance */ + mpfr_init2 (x, 59); +@@ -201,6 +310,8 @@ + + mpfr_clear (x); + ++ check_can_round (); ++ + check_round_p (); + + tests_end_mpfr ();