[arch-commits] Commit in mpfr/trunk (PKGBUILD mpfr-3.1.4-p1.patch mpfr-3.1.4-p5.patch)

Allan McRae allan at archlinux.org
Mon Sep 12 01:49:52 UTC 2016


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



More information about the arch-commits mailing list