summaryrefslogtreecommitdiff
path: root/patches/mpfr
diff options
context:
space:
mode:
authorKirill K. Smirnov <kirill.k.smirnov@gmail.com>2016-09-17 21:01:42 (GMT)
committerKirill K. Smirnov <kirill.k.smirnov@gmail.com>2016-09-17 21:01:42 (GMT)
commit2e6a56d1ccd341d5662007420dd35d120d681344 (patch)
tree9b01e356117f2e382ea54c97162f18c55ba7f408 /patches/mpfr
parentaf1850f76fd3bc54dcbed463062569498e4ec4a2 (diff)
patches: add patches for mpfr
This changeset adds official patches published on mpfr website. Signed-off-by: Kirill K. Smirnov <kirill.k.smirnov@gmail.com>
Diffstat (limited to 'patches/mpfr')
-rw-r--r--patches/mpfr/2.4.2/120-gmp5.patch75
-rw-r--r--patches/mpfr/3.0.0/110-mpfr_out_str.patch220
-rw-r--r--patches/mpfr/3.0.0/120-alloca.patch377
-rw-r--r--patches/mpfr/3.0.0/130-gamma_underflow.patch88
-rw-r--r--patches/mpfr/3.0.0/140-mpfr_cmp_set_ui_si.patch239
-rw-r--r--patches/mpfr/3.0.0/150-tcan_round.patch45
-rw-r--r--patches/mpfr/3.0.0/160-mpfr_sub1.patch628
-rw-r--r--patches/mpfr/3.0.0/170-mpfr_set_ld.patch155
-rw-r--r--patches/mpfr/3.0.0/180-macros.patch193
-rw-r--r--patches/mpfr/3.0.1/110-asin_exprange.patch137
-rw-r--r--patches/mpfr/3.0.1/120-rec_sqrt-carry.patch76
-rw-r--r--patches/mpfr/3.0.1/130-atan-expo-range.patch107
-rw-r--r--patches/mpfr/3.0.1/140-texp-zero.patch47
-rw-r--r--patches/mpfr/3.1.0/110-mpfr_unlikely.patch50
-rw-r--r--patches/mpfr/3.1.0/120-lib-search-path.patch96
-rw-r--r--patches/mpfr/3.1.0/130-vasprintf.patch247
-rw-r--r--patches/mpfr/3.1.0/140-gmp41compat.patch166
-rw-r--r--patches/mpfr/3.1.0/150-logging-freeze.patch69
-rw-r--r--patches/mpfr/3.1.0/160-logging-varfmt.patch45
-rw-r--r--patches/mpfr/3.1.0/170-large-prec.patch591
-rw-r--r--patches/mpfr/3.1.0/180-__gmp_const.patch52
-rw-r--r--patches/mpfr/3.1.0/190-gamma-underflow.patch93
-rw-r--r--patches/mpfr/3.1.0/200-gamma-overunderflow.patch487
-rw-r--r--patches/mpfr/3.1.1/110-get_decimal64.patch235
-rw-r--r--patches/mpfr/3.1.1/120-strtofr-ternary-value.patch170
-rw-r--r--patches/mpfr/3.1.1/130-gmp51-compat.patch98
-rw-r--r--patches/mpfr/3.1.2/110-exp_2.patch45
-rw-r--r--patches/mpfr/3.1.2/120-fits-smallneg.patch605
-rw-r--r--patches/mpfr/3.1.2/130-clang-divby0.patch129
-rw-r--r--patches/mpfr/3.1.2/140-printf-alt0.patch84
-rw-r--r--patches/mpfr/3.1.2/150-custom_init_set.patch42
-rw-r--r--patches/mpfr/3.1.2/160-li2-return.patch43
-rw-r--r--patches/mpfr/3.1.2/170-exp3.patch71
-rw-r--r--patches/mpfr/3.1.2/180-gmp6-compat.patch254
-rw-r--r--patches/mpfr/3.1.2/190-div-overflow.patch166
-rw-r--r--patches/mpfr/3.1.2/200-vasprintf.patch138
-rw-r--r--patches/mpfr/3.1.2/210-strtofr.patch49
-rw-r--r--patches/mpfr/3.1.3/110-lngamma-and-doc.patch1117
-rw-r--r--patches/mpfr/3.1.3/120-muldiv-2exp-overflow.patch161
-rw-r--r--patches/mpfr/3.1.3/130-muldiv-2exp-underflow.patch217
-rw-r--r--patches/mpfr/3.1.3/140-frexp.patch204
-rw-r--r--patches/mpfr/3.1.3/150-divhigh-basecase.patch131
-rw-r--r--patches/mpfr/3.1.3/160-jn.patch71
-rw-r--r--patches/mpfr/3.1.3/170-zeta.patch125
-rw-r--r--patches/mpfr/3.1.3/180-sqrt.patch97
-rw-r--r--patches/mpfr/3.1.3/190-si-ops.patch107
-rw-r--r--patches/mpfr/3.1.3/200-can_round.patch413
-rw-r--r--patches/mpfr/3.1.3/210-fits.patch584
-rw-r--r--patches/mpfr/3.1.3/220-root.patch621
-rw-r--r--patches/mpfr/3.1.3/230-gamma.patch77
-rw-r--r--patches/mpfr/3.1.3/240-rem1.patch337
-rw-r--r--patches/mpfr/3.1.3/250-agm-eq.patch105
-rw-r--r--patches/mpfr/3.1.3/260-sum.patch223
-rw-r--r--patches/mpfr/3.1.3/270-cmp_d.patch219
54 files changed, 11221 insertions, 0 deletions
diff --git a/patches/mpfr/2.4.2/120-gmp5.patch b/patches/mpfr/2.4.2/120-gmp5.patch
new file mode 100644
index 0000000..3ce4952
--- /dev/null
+++ b/patches/mpfr/2.4.2/120-gmp5.patch
@@ -0,0 +1,75 @@
+diff -Naurd mpfr-2.4.2-a/PATCHES mpfr-2.4.2-b/PATCHES
+--- mpfr-2.4.2-a/PATCHES 2010-01-11 15:27:18.000000000 +0000
++++ mpfr-2.4.2-b/PATCHES 2010-01-11 15:30:31.000000000 +0000
+@@ -0,0 +1 @@
++gmp5
+diff -Naurd mpfr-2.4.2-a/VERSION mpfr-2.4.2-b/VERSION
+--- mpfr-2.4.2-a/VERSION 2009-12-18 12:05:09.000000000 +0000
++++ mpfr-2.4.2-b/VERSION 2010-01-11 15:29:40.000000000 +0000
+@@ -1 +1 @@
+-2.4.2-p2
++2.4.2-p3
+diff -Naurd mpfr-2.4.2-a/configure mpfr-2.4.2-b/configure
+--- mpfr-2.4.2-a/configure 2009-11-30 02:44:35.000000000 +0000
++++ mpfr-2.4.2-b/configure 2010-01-11 15:28:56.000000000 +0000
+@@ -20449,6 +20449,9 @@
+ main ()
+ {
+
++#ifndef BITS_PER_MP_LIMB
++#define BITS_PER_MP_LIMB GMP_LIMB_BITS
++#endif
+ return BITS_PER_MP_LIMB == BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
+
+diff -Naurd mpfr-2.4.2-a/configure.in mpfr-2.4.2-b/configure.in
+--- mpfr-2.4.2-a/configure.in 2009-11-30 02:43:08.000000000 +0000
++++ mpfr-2.4.2-b/configure.in 2009-11-30 02:43:08.000000000 +0000
+@@ -424,6 +424,9 @@
+ #include "gmp.h"
+ #include "gmp-impl.h"
+ ]], [[
++#ifndef BITS_PER_MP_LIMB
++#define BITS_PER_MP_LIMB GMP_LIMB_BITS
++#endif
+ return BITS_PER_MP_LIMB == BYTES_PER_MP_LIMB * CHAR_BIT
+ && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
+ ]])], [AC_MSG_RESULT(yes)], [
+diff -Naurd mpfr-2.4.2-a/mpfr-impl.h mpfr-2.4.2-b/mpfr-impl.h
+--- mpfr-2.4.2-a/mpfr-impl.h 2009-11-30 02:43:08.000000000 +0000
++++ mpfr-2.4.2-b/mpfr-impl.h 2010-01-11 15:28:01.000000000 +0000
+@@ -65,6 +65,12 @@
+ # ifndef __GMP_IMPL_H__
+ # include "gmp-impl.h"
+ # endif
++# ifndef BITS_PER_MP_LIMB
++# define BITS_PER_MP_LIMB GMP_LIMB_BITS
++# endif
++#ifndef mpn_sqr_n
++# define mpn_sqr_n mpn_sqr
++#endif
+ # ifdef MPFR_NEED_LONGLONG_H
+ # include "longlong.h"
+ # endif
+diff -Naurd mpfr-2.4.2-a/mpfr.h mpfr-2.4.2-b/mpfr.h
+--- mpfr-2.4.2-a/mpfr.h 2009-12-18 12:05:09.000000000 +0000
++++ mpfr-2.4.2-b/mpfr.h 2010-01-11 15:29:40.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 2
+ #define MPFR_VERSION_MINOR 4
+ #define MPFR_VERSION_PATCHLEVEL 2
+-#define MPFR_VERSION_STRING "2.4.2-p2"
++#define MPFR_VERSION_STRING "2.4.2-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-2.4.2-a/version.c mpfr-2.4.2-b/version.c
+--- mpfr-2.4.2-a/version.c 2009-12-18 12:05:09.000000000 +0000
++++ mpfr-2.4.2-b/version.c 2010-01-11 15:29:40.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "2.4.2-p2";
++ return "2.4.2-p3";
+ }
diff --git a/patches/mpfr/3.0.0/110-mpfr_out_str.patch b/patches/mpfr/3.0.0/110-mpfr_out_str.patch
new file mode 100644
index 0000000..da98aab
--- /dev/null
+++ b/patches/mpfr/3.0.0/110-mpfr_out_str.patch
@@ -0,0 +1,220 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-06-23 11:02:49.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-06-23 11:03:36.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_out_str
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-06-23 11:03:20.000000000 +0000
+@@ -1 +1 @@
+-3.0.0
++3.0.0-p1
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-06-23 11:03:20.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0"
++#define MPFR_VERSION_STRING "3.0.0-p1"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/mpfr.texi mpfr-3.0.0-b/mpfr.texi
+--- mpfr-3.0.0-a/mpfr.texi 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.texi 2010-06-23 11:03:12.000000000 +0000
+@@ -2050,7 +2050,7 @@
+ are printed. If @var{base} is greater than 10, @samp{@@} will be used
+ instead of @samp{e} as exponent delimiter.
+
+-Return the number of bytes written, or if an error occurred, return 0.
++Return the number of characters written, or if an error occurred, return 0.
+ @end deftypefun
+
+ @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd})
+diff -Naurd mpfr-3.0.0-a/out_str.c mpfr-3.0.0-b/out_str.c
+--- mpfr-3.0.0-a/out_str.c 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/out_str.c 2010-06-23 11:03:12.000000000 +0000
+@@ -22,6 +22,16 @@
+
+ #include "mpfr-impl.h"
+
++/* Warning! S should not contain "%". */
++#define OUT_STR_RET(S) \
++ do \
++ { \
++ int r; \
++ r = fprintf (stream, (S)); \
++ return r < 0 ? 0 : r; \
++ } \
++ while (0)
++
+ size_t
+ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
+ mpfr_rnd_t rnd_mode)
+@@ -29,6 +39,7 @@
+ char *s, *s0;
+ size_t l;
+ mpfr_exp_t e;
++ int err;
+
+ MPFR_ASSERTN (base >= 2 && base <= 62);
+
+@@ -36,37 +47,16 @@
+ if (stream == NULL)
+ stream = stdout;
+
+- if (MPFR_IS_NAN(op))
+- {
+- fprintf (stream, "@NaN@");
+- return 3;
+- }
+-
+- if (MPFR_IS_INF(op))
+- {
+- if (MPFR_SIGN(op) > 0)
+- {
+- fprintf (stream, "@Inf@");
+- return 3;
+- }
+- else
+- {
+- fprintf (stream, "-@Inf@");
+- return 4;
+- }
+- }
+-
+- if (MPFR_IS_ZERO(op))
++ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
+ {
+- if (MPFR_SIGN(op) > 0)
+- {
+- fprintf(stream, "0");
+- return 1;
+- }
++ if (MPFR_IS_NAN (op))
++ OUT_STR_RET ("@NaN@");
++ else if (MPFR_IS_INF (op))
++ OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@");
+ else
+ {
+- fprintf(stream, "-0");
+- return 2;
++ MPFR_ASSERTD (MPFR_IS_ZERO (op));
++ OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0");
+ }
+ }
+
+@@ -77,21 +67,31 @@
+
+ l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str
+ - may be incorrect, as only an upper bound? */
+- if (*s == '-')
+- fputc (*s++, stream);
+
+- /* outputs mantissa */
+- fputc (*s++, stream); e--; /* leading digit */
+- fputc ((unsigned char) MPFR_DECIMAL_POINT, stream);
+- fputs (s, stream); /* rest of mantissa */
++ /* outputs possible sign and significand */
++ err = (*s == '-' && fputc (*s++, stream) == EOF)
++ || fputc (*s++, stream) == EOF /* leading digit */
++ || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
++ || fputs (s, stream) == EOF; /* trailing significand */
+ (*__gmp_free_func) (s0, l);
++ if (MPFR_UNLIKELY (err))
++ return 0;
++
++ e--; /* due to the leading digit */
+
+ /* outputs exponent */
+ if (e)
+ {
++ int r;
++
+ MPFR_ASSERTN(e >= LONG_MIN);
+ MPFR_ASSERTN(e <= LONG_MAX);
+- l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
++
++ r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
++ if (MPFR_UNLIKELY (r < 0))
++ return 0;
++
++ l += r;
+ }
+
+ return l;
+diff -Naurd mpfr-3.0.0-a/tests/tout_str.c mpfr-3.0.0-b/tests/tout_str.c
+--- mpfr-3.0.0-a/tests/tout_str.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tout_str.c 2010-06-23 11:03:12.000000000 +0000
+@@ -46,22 +46,54 @@
+ special (void)
+ {
+ mpfr_t x;
++ unsigned int n;
+
+ mpfr_init (x);
+
+ mpfr_set_nan (x);
+- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ if (n != 5)
++ {
++ printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u "
++ "characters instead of 5.\n", n);
++ exit (1);
++ }
+
+ mpfr_set_inf (x, 1);
+- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ if (n != 5)
++ {
++ printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u "
++ "characters instead of 5.\n", n);
++ exit (1);
++ }
+
+ mpfr_set_inf (x, -1);
+- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ if (n != 6)
++ {
++ printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u "
++ "characters instead of 6.\n", n);
++ exit (1);
++ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ if (n != 1)
++ {
++ printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u "
++ "characters instead of 1.\n", n);
++ exit (1);
++ }
++
+ mpfr_neg (x, x, MPFR_RNDN);
+- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++ if (n != 2)
++ {
++ printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u "
++ "characters instead of 2.\n", n);
++ exit (1);
++ }
+
+ mpfr_clear (x);
+ }
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-06-23 11:03:20.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0";
++ return "3.0.0-p1";
+ }
diff --git a/patches/mpfr/3.0.0/120-alloca.patch b/patches/mpfr/3.0.0/120-alloca.patch
new file mode 100644
index 0000000..af6dfb2
--- /dev/null
+++ b/patches/mpfr/3.0.0/120-alloca.patch
@@ -0,0 +1,377 @@
+diff -Naurd mpfr-3.0.0-a/Makefile.in mpfr-3.0.0-b/Makefile.in
+--- mpfr-3.0.0-a/Makefile.in 2010-06-10 11:00:52.000000000 +0000
++++ mpfr-3.0.0-b/Makefile.in 2010-06-10 11:00:52.000000000 +0000
+@@ -239,6 +239,7 @@
+ distuninstallcheck_listfiles = find . -type f -print
+ distcleancheck_listfiles = find . -type f -print
+ ACLOCAL = @ACLOCAL@
++ALLOCA = @ALLOCA@
+ AMTAR = @AMTAR@
+ AR = @AR@
+ AS = @AS@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-06-23 11:03:36.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-06-25 13:23:13.000000000 +0000
+@@ -0,0 +1 @@
++alloca
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-06-25 13:23:13.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p1
++3.0.0-p2
+diff -Naurd mpfr-3.0.0-a/acinclude.m4 mpfr-3.0.0-b/acinclude.m4
+--- mpfr-3.0.0-a/acinclude.m4 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/acinclude.m4 2010-06-10 11:00:14.000000000 +0000
+@@ -59,6 +59,9 @@
+ dnl sys/fpu.h - MIPS specific
+ AC_CHECK_HEADERS([sys/time.h sys/fpu.h])
+
++dnl Check how to get `alloca'
++AC_FUNC_ALLOCA
++
+ dnl SIZE_MAX macro
+ gl_SIZE_MAX
+
+diff -Naurd mpfr-3.0.0-a/configure mpfr-3.0.0-b/configure
+--- mpfr-3.0.0-a/configure 2010-06-10 11:00:51.000000000 +0000
++++ mpfr-3.0.0-b/configure 2010-06-25 13:23:05.000000000 +0000
+@@ -783,6 +783,7 @@
+ OBJDUMP
+ DLLTOOL
+ AS
++ALLOCA
+ MPFR_LIBM
+ ANSI2KNR
+ U
+@@ -5622,6 +5623,197 @@
+ done
+
+
++# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
++# for constant arguments. Useless!
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
++$as_echo_n "checking for working alloca.h... " >&6; }
++if test "${ac_cv_working_alloca_h+set}" = set; then :
++ $as_echo_n "(cached) " >&6
++else
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++#include <alloca.h>
++int
++main ()
++{
++char *p = (char *) alloca (2 * sizeof (int));
++ if (p) return 0;
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_working_alloca_h=yes
++else
++ ac_cv_working_alloca_h=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
++$as_echo "$ac_cv_working_alloca_h" >&6; }
++if test $ac_cv_working_alloca_h = yes; then
++
++$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
++
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
++$as_echo_n "checking for alloca... " >&6; }
++if test "${ac_cv_func_alloca_works+set}" = set; then :
++ $as_echo_n "(cached) " >&6
++else
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++#ifdef __GNUC__
++# define alloca __builtin_alloca
++#else
++# ifdef _MSC_VER
++# include <malloc.h>
++# define alloca _alloca
++# else
++# ifdef HAVE_ALLOCA_H
++# include <alloca.h>
++# else
++# ifdef _AIX
++ #pragma alloca
++# else
++# ifndef alloca /* predefined by HP cc +Olibcalls */
++char *alloca ();
++# endif
++# endif
++# endif
++# endif
++#endif
++
++int
++main ()
++{
++char *p = (char *) alloca (1);
++ if (p) return 0;
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_func_alloca_works=yes
++else
++ ac_cv_func_alloca_works=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
++$as_echo "$ac_cv_func_alloca_works" >&6; }
++
++if test $ac_cv_func_alloca_works = yes; then
++
++$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
++
++else
++ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
++# that cause trouble. Some versions do not even contain alloca or
++# contain a buggy version. If you still want to use their alloca,
++# use ar to extract alloca.o from them instead of compiling alloca.c.
++
++ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
++
++$as_echo "#define C_ALLOCA 1" >>confdefs.h
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
++$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
++if test "${ac_cv_os_cray+set}" = set; then :
++ $as_echo_n "(cached) " >&6
++else
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++#if defined CRAY && ! defined CRAY2
++webecray
++#else
++wenotbecray
++#endif
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++ $EGREP "webecray" >/dev/null 2>&1; then :
++ ac_cv_os_cray=yes
++else
++ ac_cv_os_cray=no
++fi
++rm -f conftest*
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
++$as_echo "$ac_cv_os_cray" >&6; }
++if test $ac_cv_os_cray = yes; then
++ for ac_func in _getb67 GETB67 getb67; do
++ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
++eval as_val=\$$as_ac_var
++ if test "x$as_val" = x""yes; then :
++
++cat >>confdefs.h <<_ACEOF
++#define CRAY_STACKSEG_END $ac_func
++_ACEOF
++
++ break
++fi
++
++ done
++fi
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
++$as_echo_n "checking stack direction for C alloca... " >&6; }
++if test "${ac_cv_c_stack_direction+set}" = set; then :
++ $as_echo_n "(cached) " >&6
++else
++ if test "$cross_compiling" = yes; then :
++ ac_cv_c_stack_direction=0
++else
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++$ac_includes_default
++int
++find_stack_direction ()
++{
++ static char *addr = 0;
++ auto char dummy;
++ if (addr == 0)
++ {
++ addr = &dummy;
++ return find_stack_direction ();
++ }
++ else
++ return (&dummy > addr) ? 1 : -1;
++}
++
++int
++main ()
++{
++ return find_stack_direction () < 0;
++}
++_ACEOF
++if ac_fn_c_try_run "$LINENO"; then :
++ ac_cv_c_stack_direction=1
++else
++ ac_cv_c_stack_direction=-1
++fi
++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
++ conftest.$ac_objext conftest.beam conftest.$ac_ext
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
++$as_echo "$ac_cv_c_stack_direction" >&6; }
++cat >>confdefs.h <<_ACEOF
++#define STACK_DIRECTION $ac_cv_c_stack_direction
++_ACEOF
++
++
++fi
++
++
+
+ for ac_header in stdint.h
+ do :
+@@ -7564,13 +7756,13 @@
+ else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+- (eval echo "\"\$as_me:7567: $ac_compile\"" >&5)
++ (eval echo "\"\$as_me:7759: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+- (eval echo "\"\$as_me:7570: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
++ (eval echo "\"\$as_me:7762: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+- (eval echo "\"\$as_me:7573: output\"" >&5)
++ (eval echo "\"\$as_me:7765: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+@@ -8772,7 +8964,7 @@
+ ;;
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 8775 "configure"' > conftest.$ac_ext
++ echo '#line 8967 "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+@@ -10032,11 +10224,11 @@
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:10035: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:10227: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:10039: \$? = $ac_status" >&5
++ echo "$as_me:10231: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -10371,11 +10563,11 @@
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:10374: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:10566: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:10378: \$? = $ac_status" >&5
++ echo "$as_me:10570: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -10476,11 +10668,11 @@
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:10479: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:10671: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:10483: \$? = $ac_status" >&5
++ echo "$as_me:10675: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -10531,11 +10723,11 @@
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:10534: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:10726: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:10538: \$? = $ac_status" >&5
++ echo "$as_me:10730: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -12915,7 +13107,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 12918 "configure"
++#line 13110 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -13011,7 +13203,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 13014 "configure"
++#line 13206 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-06-25 13:23:13.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p1"
++#define MPFR_VERSION_STRING "3.0.0-p2"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/tests/Makefile.in mpfr-3.0.0-b/tests/Makefile.in
+--- mpfr-3.0.0-a/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000
++++ mpfr-3.0.0-b/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000
+@@ -960,6 +960,7 @@
+ red=; grn=; lgn=; blu=; std=
+ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ ACLOCAL = @ACLOCAL@
++ALLOCA = @ALLOCA@
+ AMTAR = @AMTAR@
+ AR = @AR@
+ AS = @AS@
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-06-25 13:23:13.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p1";
++ return "3.0.0-p2";
+ }
diff --git a/patches/mpfr/3.0.0/130-gamma_underflow.patch b/patches/mpfr/3.0.0/130-gamma_underflow.patch
new file mode 100644
index 0000000..cf8a936
--- /dev/null
+++ b/patches/mpfr/3.0.0/130-gamma_underflow.patch
@@ -0,0 +1,88 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-07-10 00:11:19.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-07-10 00:12:50.000000000 +0000
+@@ -0,0 +1 @@
++gamma_underflow
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-07-10 00:11:53.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p2
++3.0.0-p3
+diff -Naurd mpfr-3.0.0-a/gamma.c mpfr-3.0.0-b/gamma.c
+--- mpfr-3.0.0-a/gamma.c 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/gamma.c 2010-07-10 00:11:46.000000000 +0000
+@@ -274,7 +274,7 @@
+ /* we want an upper bound for x * [log(2-x)-1].
+ since x < 0, we need a lower bound on log(2-x) */
+ mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
+- mpfr_log (xp, xp, MPFR_RNDD);
++ mpfr_log2 (xp, xp, MPFR_RNDD);
+ mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
+ mpfr_mul (xp, xp, x, MPFR_RNDU);
+
+@@ -303,8 +303,8 @@
+ {
+ mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */
+ mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */
+- mpfr_log (tmp, tmp, MPFR_RNDU);
+- mpfr_add (tmp, tmp, xp, MPFR_RNDU);
++ mpfr_log2 (tmp, tmp, MPFR_RNDU);
++ mpfr_add (xp, tmp, xp, MPFR_RNDU);
+ underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0;
+ }
+
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-07-10 00:11:53.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p2"
++#define MPFR_VERSION_STRING "3.0.0-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/tests/tgamma.c mpfr-3.0.0-b/tests/tgamma.c
+--- mpfr-3.0.0-a/tests/tgamma.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tgamma.c 2010-07-10 00:11:46.000000000 +0000
+@@ -461,6 +461,20 @@
+ mpfr_clear (x);
+ }
+
++/* bug found by Stathis, only occurs on 32-bit machines */
++static void
++test20100709 (void)
++{
++ mpfr_t x;
++ int inex;
++
++ mpfr_init2 (x, 100);
++ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
++ inex = mpfr_gamma (x, x, MPFR_RNDN);
++ MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
++ mpfr_clear (x);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -471,6 +485,7 @@
+ test_generic (2, 100, 2);
+ gamma_integer ();
+ test20071231 ();
++ test20100709 ();
+
+ data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
+
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-07-10 00:11:53.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p2";
++ return "3.0.0-p3";
+ }
diff --git a/patches/mpfr/3.0.0/140-mpfr_cmp_set_ui_si.patch b/patches/mpfr/3.0.0/140-mpfr_cmp_set_ui_si.patch
new file mode 100644
index 0000000..67d6a6a
--- /dev/null
+++ b/patches/mpfr/3.0.0/140-mpfr_cmp_set_ui_si.patch
@@ -0,0 +1,239 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-09-07 08:44:01.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-09-07 08:48:46.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_cmp/set_ui/si
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-09-07 08:46:06.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p3
++3.0.0-p4
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-09-07 08:46:06.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p3"
++#define MPFR_VERSION_STRING "3.0.0-p4"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -798,35 +798,45 @@
+ anyway. Checking with other ICC versions is needed. Possibly detect
+ whether warnings are produced or not with a configure test.
+ + Remove C++ too, since it complains too much. */
++/* Added casts to improve robustness in case of undefined behavior and
++ compiler extensions based on UB (in particular -fwrapv). MPFR doesn't
++ use such extensions, but these macros will be used by 3rd-party code,
++ where such extensions may be required.
++ Moreover casts to unsigned long have been added to avoid warnings in
++ programs that use MPFR and are compiled with -Wconversion; such casts
++ are OK since if X is a constant expression, then (unsigned long) X is
++ also a constant expression, so that the optimizations still work. */
+ #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
+ #if (__GNUC__ >= 2)
+ #undef mpfr_cmp_ui
+-/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0. */
+-#define mpfr_cmp_ui(_f,_u) \
+- (__builtin_constant_p (_u) && (_u) == 0 ? \
+- mpfr_sgn (_f) : \
+- mpfr_cmp_ui_2exp ((_f),(_u),0))
++/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0.
++ But warning! mpfr_sgn is specified as a macro in the API, thus the macro
++ mustn't be used if side effects are possible, like here. */
++#define mpfr_cmp_ui(_f,_u) \
++ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
++ (mpfr_sgn) (_f) : \
++ mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
+ #undef mpfr_cmp_si
+-#define mpfr_cmp_si(_f,_s) \
+- (__builtin_constant_p (_s) && (_s) >= 0 ? \
+- mpfr_cmp_ui ((_f), (_s)) : \
+- mpfr_cmp_si_2exp ((_f), (_s), 0))
++#define mpfr_cmp_si(_f,_s) \
++ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
++ mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \
++ mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
+ #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
+ #undef mpfr_set_ui
+-#define mpfr_set_ui(_f,_u,_r) \
+- (__builtin_constant_p (_u) && (_u) == 0 ? \
+- __extension__ ({ \
+- mpfr_ptr _p = (_f); \
+- _p->_mpfr_sign = 1; \
+- _p->_mpfr_exp = __MPFR_EXP_ZERO; \
+- (void) (_r); 0; }) : \
+- mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
++#define mpfr_set_ui(_f,_u,_r) \
++ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
++ __extension__ ({ \
++ mpfr_ptr _p = (_f); \
++ _p->_mpfr_sign = 1; \
++ _p->_mpfr_exp = __MPFR_EXP_ZERO; \
++ (void) (_r); 0; }) : \
++ mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
+ #endif
+ #undef mpfr_set_si
+-#define mpfr_set_si(_f,_s,_r) \
+- (__builtin_constant_p (_s) && (_s) >= 0 ? \
+- mpfr_set_ui ((_f), (_s), (_r)) : \
+- mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
++#define mpfr_set_si(_f,_s,_r) \
++ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
++ mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \
++ mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
+ #endif
+ #endif
+
+diff -Naurd mpfr-3.0.0-a/tests/tcmp_ui.c mpfr-3.0.0-b/tests/tcmp_ui.c
+--- mpfr-3.0.0-a/tests/tcmp_ui.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tcmp_ui.c 2010-09-07 08:45:12.000000000 +0000
+@@ -88,6 +88,126 @@
+ mpfr_clear (x);
+ }
+
++/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro
++ with __builtin_constant_p for GCC, check that side effects are
++ handled correctly. */
++static void
++check_macros (void)
++{
++ mpfr_t x;
++ int c;
++
++ mpfr_init2 (x, 32);
++
++ c = 0;
++ mpfr_set_ui (x, 17, MPFR_RNDN);
++ if (mpfr_cmp_ui (x, 17) != 0)
++ {
++ printf ("Error 1 on mpfr_cmp_ui(x,17) in check_macros\n");
++ exit (1);
++ }
++ if (mpfr_cmp_ui (x, (c++, 17)) != 0)
++ {
++ printf ("Error 2 on mpfr_cmp_ui(x,17) in check_macros\n");
++ exit (1);
++ }
++ if (c != 1)
++ {
++ printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n"
++ "(c = %d instead of 1)\n", c);
++ exit (1);
++ }
++ if (mpfr_cmp_si (x, 17) != 0)
++ {
++ printf ("Error 1 on mpfr_cmp_si(x,17) in check_macros\n");
++ exit (1);
++ }
++ if (mpfr_cmp_si (x, (c++, 17)) != 0)
++ {
++ printf ("Error 2 on mpfr_cmp_si(x,17) in check_macros\n");
++ exit (1);
++ }
++ if (c != 2)
++ {
++ printf ("Error 3 on mpfr_cmp_si(x,17) in check_macros\n"
++ "(c = %d instead of 2)\n", c);
++ exit (1);
++ }
++
++ c = 0;
++ mpfr_set_ui (x, 0, MPFR_RNDN);
++ if (mpfr_cmp_ui (x, 0) != 0)
++ {
++ printf ("Error 1 on mpfr_cmp_ui(x,0) in check_macros\n");
++ exit (1);
++ }
++ if (mpfr_cmp_ui (x, (c++, 0)) != 0)
++ {
++ printf ("Error 2 on mpfr_cmp_ui(x,0) in check_macros\n");
++ exit (1);
++ }
++ if (c != 1)
++ {
++ printf ("Error 3 on mpfr_cmp_ui(x,0) in check_macros\n"
++ "(c = %d instead of 1)\n", c);
++ exit (1);
++ }
++ if (mpfr_cmp_si (x, 0) != 0)
++ {
++ printf ("Error 1 on mpfr_cmp_si(x,0) in check_macros\n");
++ exit (1);
++ }
++ if (mpfr_cmp_si (x, (c++, 0)) != 0)
++ {
++ printf ("Error 2 on mpfr_cmp_si(x,0) in check_macros\n");
++ exit (1);
++ }
++ if (c != 2)
++ {
++ printf ("Error 3 on mpfr_cmp_si(x,0) in check_macros\n"
++ "(c = %d instead of 2)\n", c);
++ exit (1);
++ }
++
++ mpfr_clear (x);
++}
++
++/* Bug in r7114 */
++static void
++test_macros (void)
++{
++ mpfr_t x[3];
++ mpfr_ptr p;
++
++ mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
++ mpfr_set_ui (x[0], 0, MPFR_RNDN);
++ p = x[0];
++ if (mpfr_cmp_ui (p++, 0) != 0)
++ {
++ printf ("Error in mpfr_cmp_ui macro: result should be 0.\n");
++ exit (1);
++ }
++ if (p != x[1])
++ {
++ printf ("Error in mpfr_cmp_ui macro: p - x[0] = %d (expecting 1)\n",
++ (int) (p - x[0]));
++ exit (1);
++ }
++ p = x[0];
++ if (mpfr_cmp_si (p++, 0) != 0)
++ {
++ printf ("Error in mpfr_cmp_si macro: result should be 0.\n");
++ exit (1);
++ }
++ if (p != x[1])
++ {
++ printf ("Error in mpfr_cmp_si macro: p - x[0] = %d (expecting 1)\n",
++ (int) (p - x[0]));
++ exit (1);
++ }
++ mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
++}
++
+ int
+ main (void)
+ {
+@@ -216,6 +336,8 @@
+ mpfr_clear (x);
+
+ check_nan ();
++ check_macros ();
++ test_macros ();
+
+ tests_end_mpfr ();
+ return 0;
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-09-07 08:46:06.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p3";
++ return "3.0.0-p4";
+ }
diff --git a/patches/mpfr/3.0.0/150-tcan_round.patch b/patches/mpfr/3.0.0/150-tcan_round.patch
new file mode 100644
index 0000000..292e7a5
--- /dev/null
+++ b/patches/mpfr/3.0.0/150-tcan_round.patch
@@ -0,0 +1,45 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:28:38.000000000 +0000
+@@ -0,0 +1 @@
++tcan_round
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-10-21 20:28:38.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p4
++3.0.0-p5
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:28:38.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p4"
++#define MPFR_VERSION_STRING "3.0.0-p5"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/tests/tcan_round.c mpfr-3.0.0-b/tests/tcan_round.c
+--- mpfr-3.0.0-a/tests/tcan_round.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tcan_round.c 2010-10-21 20:28:38.000000000 +0000
+@@ -41,7 +41,7 @@
+ /* avoid mpn_random which leaks memory */
+ for (i = 0; i < n; i++)
+ buf[i] = randlimb ();
+- p = (mpfr_prec_t) randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
++ p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
+ err = p + randlimb () % GMP_NUMB_BITS;
+ r1 = mpfr_round_p (buf, n, err, p);
+ r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-10-21 20:28:38.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p4";
++ return "3.0.0-p5";
+ }
diff --git a/patches/mpfr/3.0.0/160-mpfr_sub1.patch b/patches/mpfr/3.0.0/160-mpfr_sub1.patch
new file mode 100644
index 0000000..2ce98e9
--- /dev/null
+++ b/patches/mpfr/3.0.0/160-mpfr_sub1.patch
@@ -0,0 +1,628 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:59:32.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_sub1
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-10-21 20:59:32.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p5
++3.0.0-p6
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:59:32.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p5"
++#define MPFR_VERSION_STRING "3.0.0-p6"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/sub1.c mpfr-3.0.0-b/sub1.c
+--- mpfr-3.0.0-a/sub1.c 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/sub1.c 2010-10-21 20:59:32.000000000 +0000
+@@ -37,7 +37,9 @@
+ mp_size_t cancel2, an, bn, cn, cn0;
+ mp_limb_t *ap, *bp, *cp;
+ mp_limb_t carry, bb, cc, borrow = 0;
+- int inexact, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0;
++ int inexact, shift_b, shift_c, add_exp = 0;
++ int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
++ negative if low(b) < low(c), positive if low(b)>low(c) */
+ int sh, k;
+ MPFR_TMP_DECL(marker);
+
+@@ -196,7 +198,8 @@
+ }
+
+ #ifdef DEBUG
+- printf ("shift_b=%d shift_c=%d diffexp=%lu\n", shift_b, shift_c,
++ printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
++ mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
+ (unsigned long) diff_exp);
+ #endif
+
+@@ -307,17 +310,18 @@
+ {
+ if (MPFR_LIKELY(sh))
+ {
+- is_exact = (carry == 0);
+ /* can decide except when carry = 2^(sh-1) [middle]
+ or carry = 0 [truncate, but cannot decide inexact flag] */
+- down = (carry < (MPFR_LIMB_ONE << (sh - 1)));
+ if (carry > (MPFR_LIMB_ONE << (sh - 1)))
+ goto add_one_ulp;
+- else if ((0 < carry) && down)
++ else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1))))
+ {
+ inexact = -1; /* result if smaller than exact value */
+ goto truncate;
+ }
++ /* now carry = 2^(sh-1), in which case cmp_low=2,
++ or carry = 0, in which case cmp_low=0 */
++ cmp_low = (carry == 0) ? 0 : 2;
+ }
+ }
+ else /* directed rounding: set rnd_mode to RNDZ iff toward zero */
+@@ -344,12 +348,32 @@
+ cn -= (long int) an + cancel2;
+
+ #ifdef DEBUG
+- printf ("last %d bits from a are %lu, bn=%ld, cn=%ld\n",
++ printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
+ sh, (unsigned long) carry, (long) bn, (long) cn);
+ #endif
+
++ /* for rounding to nearest, we couldn't conclude up to here in the following
++ cases:
++ 1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp
++ or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp
++ 2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1):
++ -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp
++ we can't decide the rounding, in that case cmp_low=2:
++ either we truncate and flag=-1, or we add one ulp and flag=1
++ 3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to
++ truncate but we can't decide the ternary value, here cmp_low=0:
++ -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp
++ we always truncate and inexact can be any of -1,0,1
++ */
++
++ /* note: here cn might exceed cn0, in which case we consider a zero limb */
+ for (k = 0; (bn > 0) || (cn > 0); k = 1)
+ {
++ /* if cmp_low < 0, we know low(b) - low(c) < 0
++ if cmp_low > 0, we know low(b) - low(c) > 0
++ (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far)
++ if cmp_low = 0, so far low(b) - low(c) = 0 */
++
+ /* get next limbs */
+ bb = (bn > 0) ? bp[--bn] : 0;
+ if ((cn > 0) && (cn-- <= cn0))
+@@ -357,76 +381,115 @@
+ else
+ cc = 0;
+
+- /* down is set when low(b) < low(c) */
+- if (down == 0)
+- down = (bb < cc);
++ /* cmp_low compares low(b) and low(c) */
++ if (cmp_low == 0) /* case 1 or 3 */
++ cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0;
++
++ /* Case 1 for k=0 splits into 7 subcases:
++ 1a: bb > cc + half
++ 1b: bb = cc + half
++ 1c: 0 < bb - cc < half
++ 1d: bb = cc
++ 1e: -half < bb - cc < 0
++ 1f: bb - cc = -half
++ 1g: bb - cc < -half
++
++ Case 2 splits into 3 subcases:
++ 2a: bb > cc
++ 2b: bb = cc
++ 2c: bb < cc
++
++ Case 3 splits into 3 subcases:
++ 3a: bb > cc
++ 3b: bb = cc
++ 3c: bb < cc
++ */
+
+ /* the case rounding to nearest with sh=0 is special since one couldn't
+ subtract above 1/2 ulp in the trailing limb of the result */
+- if ((rnd_mode == MPFR_RNDN) && sh == 0 && k == 0)
++ if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */
+ {
+ mp_limb_t half = MPFR_LIMB_HIGHBIT;
+
+- is_exact = (bb == cc);
+-
+ /* add one ulp if bb > cc + half
+ truncate if cc - half < bb < cc + half
+ sub one ulp if bb < cc - half
+ */
+
+- if (down)
++ if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0,
++ cases 1e, 1f and 1g */
+ {
+ if (cc >= half)
+ cc -= half;
+- else
++ else /* since bb < cc < half, bb+half < 2*half */
+ bb += half;
++ /* now we have bb < cc + half:
++ we have to subtract one ulp if bb < cc,
++ and truncate if bb > cc */
+ }
+- else /* bb >= cc */
++ else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */
+ {
+ if (cc < half)
+ cc += half;
+- else
++ else /* since bb >= cc >= half, bb - half >= 0 */
+ bb -= half;
++ /* now we have bb > cc - half: we have to add one ulp if bb > cc,
++ and truncate if bb < cc */
++ if (cmp_low > 0)
++ cmp_low = 2;
+ }
+ }
+
+ #ifdef DEBUG
+- printf (" bb=%lu cc=%lu down=%d is_exact=%d\n",
+- (unsigned long) bb, (unsigned long) cc, down, is_exact);
++ printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
++ (unsigned long) bb, (unsigned long) cc, cmp_low);
+ #endif
+- if (bb < cc)
++ if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
++ one ulp */
+ {
+ if (rnd_mode == MPFR_RNDZ)
+- goto sub_one_ulp;
++ goto sub_one_ulp; /* set inexact=-1 */
+ else if (rnd_mode != MPFR_RNDN) /* round away */
+ {
+ inexact = 1;
+ goto truncate;
+ }
+- else /* round to nearest: special case here since for sh=k=0
+- bb = bb0 - MPFR_LIMB_HIGHBIT */
++ else /* round to nearest */
+ {
+- if (is_exact && sh == 0)
+- {
+- /* For k=0 we can't decide exactness since it may depend
+- from low order bits.
+- For k=1, the first low limbs matched: low(b)-low(c)<0. */
+- if (k)
+- {
+- inexact = 1;
+- goto truncate;
+- }
+- }
+- else if (down && sh == 0)
+- goto sub_one_ulp;
+- else
+- {
+- inexact = (is_exact) ? 1 : -1;
++ /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0,
++ whatever the value of sh.
++ If sh>0, then cmp_low < 0 implies that the initial neglected
++ sh bits were 0 (otherwise cmp_low=2 initially), thus the
++ weight of the new bits is less than 0.5 ulp too.
++ If k > 0 (and sh=0) this means that either the first neglected
++ limbs bb and cc were equal (thus cmp_low was 0 for k=0),
++ or we had bb - cc = -0.5 ulp or 0.5 ulp.
++ The last case is not possible here since we would have
++ cmp_low > 0 which is sticky.
++ In the first case (where we have cmp_low = -1), we truncate,
++ whereas in the 2nd case we have cmp_low = -2 and we subtract
++ one ulp.
++ */
++ if (bb > cc || sh > 0 || cmp_low == -1)
++ { /* -0.5 ulp < low(b)-low(c) < 0,
++ bb > cc corresponds to cases 1e and 1f1
++ sh > 0 corresponds to cases 3c and 3b3
++ cmp_low = -1 corresponds to case 1d3 (also 3b3) */
++ inexact = 1;
+ goto truncate;
+ }
++ else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp,
++ this corresponds to cases 1g and 1f3 */
++ goto sub_one_ulp;
++ /* the only case where we can't conclude is sh=0 and bb=cc,
++ i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus
++ we don't know if we must truncate or subtract one ulp.
++ Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to
++ now, since low(b) - low(c) > 1/2^sh */
+ }
+ }
+- else if (bb > cc)
++ else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or
++ add one ulp */
+ {
+ if (rnd_mode == MPFR_RNDZ)
+ {
+@@ -437,34 +500,70 @@
+ goto add_one_ulp;
+ else /* round to nearest */
+ {
+- if (is_exact)
++ if (bb > cc)
+ {
+- inexact = -1;
+- goto truncate;
++ /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp,
++ and similarly when cmp_low=2 */
++ if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */
++ goto add_one_ulp;
++ /* sh > 0 and cmp_low > 0: this implies that the sh initial
++ neglected bits were 0, and the remaining low(b)-low(c)>0,
++ but its weight is less than 0.5 ulp */
++ else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to
++ cases 3a, 1d1 and 3b1 */
++ {
++ inexact = -1;
++ goto truncate;
++ }
+ }
+- else if (down)
++ else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c,
++ 1b3, 2b3 and 2c */
+ {
+- inexact = 1;
++ inexact = -1;
+ goto truncate;
+ }
+- else
+- goto add_one_ulp;
++ /* the only case where we can't conclude is bb=cc, i.e.,
++ low(b) - low(c) = 0.5 ulp (up to now), thus we don't know
++ if we must truncate or add one ulp. */
+ }
+ }
++ /* after k=0, we cannot conclude in the following cases, we split them
++ according to the values of bb and cc for k=1:
++ 1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp]
++ 1b1. bb > cc: add one ulp, inex = 1
++ 1b2: bb = cc: cannot conclude
++ 1b3: bb < cc: truncate, inex = -1
++ 1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0]
++ 1d1: bb > cc: truncate, inex = -1
++ 1d2: bb = cc: cannot conclude
++ 1d3: bb < cc: truncate, inex = +1
++ 1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp]
++ 1f1: bb > cc: truncate, inex = +1
++ 1f2: bb = cc: cannot conclude
++ 1f3: bb < cc: sub one ulp, inex = -1
++ 2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp]
++ 2b1. bb > cc: add one ulp, inex = 1
++ 2b2: bb = cc: cannot conclude
++ 2b3: bb < cc: truncate, inex = -1
++ 3b. sh > 0 and cmp_low = 0 [around 0]
++ 3b1. bb > cc: truncate, inex = -1
++ 3b2: bb = cc: cannot conclude
++ 3b3: bb < cc: truncate, inex = +1
++ */
+ }
+
+- if ((rnd_mode == MPFR_RNDN) && !is_exact)
++ if ((rnd_mode == MPFR_RNDN) && cmp_low != 0)
+ {
+ /* even rounding rule */
+ if ((ap[0] >> sh) & 1)
+ {
+- if (down)
++ if (cmp_low < 0)
+ goto sub_one_ulp;
+ else
+ goto add_one_ulp;
+ }
+ else
+- inexact = (down) ? 1 : -1;
++ inexact = (cmp_low > 0) ? -1 : 1;
+ }
+ else
+ inexact = 0;
+diff -Naurd mpfr-3.0.0-a/tests/tfma.c mpfr-3.0.0-b/tests/tfma.c
+--- mpfr-3.0.0-a/tests/tfma.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tfma.c 2010-10-21 20:59:32.000000000 +0000
+@@ -337,6 +337,94 @@
+ mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
+ }
+
++static void
++bug20101018 (void)
++{
++ mpfr_t x, y, z, t, u;
++ int i;
++
++ mpfr_init2 (x, 64);
++ mpfr_init2 (y, 64);
++ mpfr_init2 (z, 64);
++ mpfr_init2 (t, 64);
++ mpfr_init2 (u, 64);
++
++ mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN);
++ mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN);
++ mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN);
++ mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN);
++ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
++ if (mpfr_cmp (u, t) != 0)
++ {
++ printf ("Wrong result in bug20101018 (a)\n");
++ printf ("Expected ");
++ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
++ printf ("\nGot ");
++ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++ if (i <= 0)
++ {
++ printf ("Wrong ternary value in bug20101018 (a)\n");
++ printf ("Expected > 0\n");
++ printf ("Got %d\n", i);
++ exit (1);
++ }
++
++ mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN);
++ mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN);
++ mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN);
++ mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN);
++ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
++ if (mpfr_cmp (u, t) != 0)
++ {
++ printf ("Wrong result in bug20101018 (b)\n");
++ printf ("Expected ");
++ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
++ printf ("\nGot ");
++ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++ if (i <= 0)
++ {
++ printf ("Wrong ternary value in bug20101018 (b)\n");
++ printf ("Expected > 0\n");
++ printf ("Got %d\n", i);
++ exit (1);
++ }
++
++ mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN);
++ mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN);
++ mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN);
++ mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN);
++ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
++ if (mpfr_cmp (u, t) != 0)
++ {
++ printf ("Wrong result in bug20101018 (c)\n");
++ printf ("Expected ");
++ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
++ printf ("\nGot ");
++ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++ if (i <= 0)
++ {
++ printf ("Wrong ternary value in bug20101018 (c)\n");
++ printf ("Expected > 0\n");
++ printf ("Got %d\n", i);
++ exit (1);
++ }
++
++ mpfr_clear (x);
++ mpfr_clear (y);
++ mpfr_clear (z);
++ mpfr_clear (t);
++ mpfr_clear (u);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -345,6 +433,8 @@
+
+ tests_start_mpfr ();
+
++ bug20101018 ();
++
+ mpfr_init (x);
+ mpfr_init (s);
+ mpfr_init (y);
+diff -Naurd mpfr-3.0.0-a/tests/tsub.c mpfr-3.0.0-b/tests/tsub.c
+--- mpfr-3.0.0-a/tests/tsub.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tsub.c 2010-10-21 20:59:32.000000000 +0000
+@@ -201,6 +201,8 @@
+ if (mpfr_cmp (z, x))
+ {
+ printf ("Error in mpfr_sub (2)\n");
++ printf ("Expected "); mpfr_print_binary (x); puts ("");
++ printf ("Got "); mpfr_print_binary (z); puts ("");
+ exit (1);
+ }
+ mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
+@@ -478,6 +480,156 @@
+ mpfr_clear (u);
+ }
+
++/* Bug found by Jakub Jelinek
++ * http://bugzilla.redhat.com/643657
++ * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301
++ * The consequence can be either an assertion failure (i = 2 in the
++ * testcase below, in debug mode) or an incorrectly rounded value.
++ */
++static void
++bug20101017 (void)
++{
++ mpfr_t a, b, c;
++ int inex;
++ int i;
++
++ mpfr_init2 (a, GMP_NUMB_BITS * 2);
++ mpfr_init2 (b, GMP_NUMB_BITS);
++ mpfr_init2 (c, GMP_NUMB_BITS);
++
++ /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1
++ with N = GMP_NUMB_BITS and k = 0 or 1.
++ c = a - b should round to the same value as a. */
++
++ for (i = 2; i <= 3; i++)
++ {
++ mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN);
++ mpfr_add_ui (a, a, 1, MPFR_RNDN);
++ mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN);
++ mpfr_set_ui (b, 1, MPFR_RNDN);
++ inex = mpfr_sub (c, a, b, MPFR_RNDN);
++ mpfr_set (b, a, MPFR_RNDN);
++ if (! mpfr_equal_p (c, b))
++ {
++ printf ("Error in bug20101017 for i = %d.\n", i);
++ printf ("Expected ");
++ mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN);
++ putchar ('\n');
++ printf ("Got ");
++ mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN);
++ putchar ('\n');
++ exit (1);
++ }
++ if (inex >= 0)
++ {
++ printf ("Error in bug20101017 for i = %d: bad inex value.\n", i);
++ printf ("Expected negative, got %d.\n", inex);
++ exit (1);
++ }
++ }
++
++ mpfr_set_prec (a, 64);
++ mpfr_set_prec (b, 129);
++ mpfr_set_prec (c, 2);
++ mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65");
++ mpfr_set_str_binary (c, "0.10E1");
++ inex = mpfr_sub (a, b, c, MPFR_RNDN);
++ if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0)
++ {
++ printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n");
++ printf ("Expected result 2^64 with inex < 0\n");
++ printf ("Got "); mpfr_print_binary (a);
++ printf (" with inex=%d\n", inex);
++ exit (1);
++ }
++
++ mpfr_clears (a, b, c, (mpfr_ptr) 0);
++}
++
++/* hard test of rounding */
++static void
++check_rounding (void)
++{
++ mpfr_t a, b, c, res;
++ mpfr_prec_t p;
++ long k, l;
++ int i;
++
++#define MAXKL (2 * GMP_NUMB_BITS)
++ for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++)
++ {
++ mpfr_init2 (a, p);
++ mpfr_init2 (res, p);
++ mpfr_init2 (b, p + 1 + MAXKL);
++ mpfr_init2 (c, MPFR_PREC_MIN);
++
++ /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */
++ for (k = 0; k <= MAXKL; k++)
++ for (l = 0; l <= MAXKL; l++)
++ {
++ mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN);
++ mpfr_add_ui (b, b, 1, MPFR_RNDN);
++ mpfr_mul_2ui (b, b, k, MPFR_RNDN);
++ mpfr_add_ui (b, b, 1, MPFR_RNDN);
++ mpfr_div_2ui (b, b, k, MPFR_RNDN);
++ mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN);
++ i = mpfr_sub (a, b, c, MPFR_RNDN);
++ /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to
++ 2^p for l <= k, and 2^p+2 for l < k */
++ if (l <= k)
++ {
++ if (mpfr_cmp_ui_2exp (a, 1, p) != 0)
++ {
++ printf ("Wrong result in check_rounding\n");
++ printf ("p=%lu k=%ld l=%ld\n", p, k, l);
++ printf ("b="); mpfr_print_binary (b); puts ("");
++ printf ("c="); mpfr_print_binary (c); puts ("");
++ printf ("Expected 2^%lu\n", p);
++ printf ("Got "); mpfr_print_binary (a); puts ("");
++ exit (1);
++ }
++ if (i >= 0)
++ {
++ printf ("Wrong ternary value in check_rounding\n");
++ printf ("p=%lu k=%ld l=%ld\n", p, k, l);
++ printf ("b="); mpfr_print_binary (b); puts ("");
++ printf ("c="); mpfr_print_binary (c); puts ("");
++ printf ("a="); mpfr_print_binary (a); puts ("");
++ printf ("Expected < 0, got %d\n", i);
++ exit (1);
++ }
++ }
++ else /* l < k */
++ {
++ mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN);
++ mpfr_add_ui (res, res, 2, MPFR_RNDN);
++ if (mpfr_cmp (a, res) != 0)
++ {
++ printf ("Wrong result in check_rounding\n");
++ printf ("b="); mpfr_print_binary (b); puts ("");
++ printf ("c="); mpfr_print_binary (c); puts ("");
++ printf ("Expected "); mpfr_print_binary (res); puts ("");
++ printf ("Got "); mpfr_print_binary (a); puts ("");
++ exit (1);
++ }
++ if (i <= 0)
++ {
++ printf ("Wrong ternary value in check_rounding\n");
++ printf ("b="); mpfr_print_binary (b); puts ("");
++ printf ("c="); mpfr_print_binary (c); puts ("");
++ printf ("Expected > 0, got %d\n", i);
++ exit (1);
++ }
++ }
++ }
++
++ mpfr_clear (a);
++ mpfr_clear (res);
++ mpfr_clear (b);
++ mpfr_clear (c);
++ }
++}
++
+ #define TEST_FUNCTION test_sub
+ #define TWO_ARGS
+ #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+@@ -491,6 +643,8 @@
+
+ tests_start_mpfr ();
+
++ bug20101017 ();
++ check_rounding ();
+ check_diverse ();
+ check_inexact ();
+ bug_ddefour ();
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-10-21 20:59:32.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p5";
++ return "3.0.0-p6";
+ }
diff --git a/patches/mpfr/3.0.0/170-mpfr_set_ld.patch b/patches/mpfr/3.0.0/170-mpfr_set_ld.patch
new file mode 100644
index 0000000..9209afe
--- /dev/null
+++ b/patches/mpfr/3.0.0/170-mpfr_set_ld.patch
@@ -0,0 +1,155 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-10-21 21:18:26.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_set_ld
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-10-21 21:18:26.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p6
++3.0.0-p7
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-10-21 21:18:26.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p6"
++#define MPFR_VERSION_STRING "3.0.0-p7"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0-a/set_ld.c mpfr-3.0.0-b/set_ld.c
+--- mpfr-3.0.0-a/set_ld.c 2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0-b/set_ld.c 2010-10-21 21:18:26.000000000 +0000
+@@ -102,21 +102,25 @@
+ {
+ x /= div13; /* exact */
+ shift_exp += 8192;
++ mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div12)
+ {
+ x /= div12; /* exact */
+ shift_exp += 4096;
++ mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div11)
+ {
+ x /= div11; /* exact */
+ shift_exp += 2048;
++ mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
+ }
+ if (ABS (x) >= div10)
+ {
+ x /= div10; /* exact */
+ shift_exp += 1024;
++ mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
+ }
+ /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
+ therefore we have one extra exponent reduction step */
+@@ -124,9 +128,10 @@
+ {
+ x /= div9; /* exact */
+ shift_exp += 512;
++ mpfr_div_2si (t, t, 512, MPFR_RNDZ);
+ }
+ } /* Check overflow of double */
+- else
++ else /* no overflow on double */
+ {
+ long double div9, div10, div11;
+
+@@ -149,29 +154,34 @@
+ {
+ x /= div13; /* exact */
+ shift_exp -= 8192;
++ mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div12)
+ {
+ x /= div12; /* exact */
+ shift_exp -= 4096;
++ mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div11)
+ {
+ x /= div11; /* exact */
+ shift_exp -= 2048;
++ mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
+ }
+ if (ABS (x) <= div10)
+ {
+ x /= div10; /* exact */
+ shift_exp -= 1024;
++ mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
+ }
+ if (ABS(x) <= div9)
+ {
+ x /= div9; /* exact */
+ shift_exp -= 512;
++ mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
+ }
+ }
+- else
++ else /* no underflow */
+ {
+ inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
+ MPFR_ASSERTD (inexact == 0);
+diff -Naurd mpfr-3.0.0-a/tests/tset_ld.c mpfr-3.0.0-b/tests/tset_ld.c
+--- mpfr-3.0.0-a/tests/tset_ld.c 2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0-b/tests/tset_ld.c 2010-10-21 21:18:26.000000000 +0000
+@@ -147,12 +147,39 @@
+ test_fixed_bugs (void)
+ {
+ mpfr_t x;
+- long double d;
++ long double l, m;
+
+ /* bug found by Steve Kargl (2009-03-14) */
+ mpfr_init2 (x, 64);
+ mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
+- d = mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
++ mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
++
++ /* bug reported by Jakub Jelinek (2010-10-17)
++ https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
++ mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
++ /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
++ l = 8.215640181713713164092636634579e-276;
++ mpfr_set_ld (x, l, MPFR_RNDN);
++ m = mpfr_get_ld (x, MPFR_RNDN);
++ if (m != l)
++ {
++ printf ("Error in get_ld o set_ld for l=%Le\n", l);
++ printf ("Got m=%Le instead of l\n", m);
++ exit (1);
++ }
++
++ /* another similar test which failed with extended double precision and the
++ generic code for mpfr_set_ld */
++ /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
++ l = 4.560596445887084662336528403703e-292;
++ mpfr_set_ld (x, l, MPFR_RNDN);
++ m = mpfr_get_ld (x, MPFR_RNDN);
++ if (m != l)
++ {
++ printf ("Error in get_ld o set_ld for l=%Le\n", l);
++ printf ("Got m=%Le instead of l\n", m);
++ exit (1);
++ }
+
+ mpfr_clear (x);
+ }
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-10-21 21:18:26.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p6";
++ return "3.0.0-p7";
+ }
diff --git a/patches/mpfr/3.0.0/180-macros.patch b/patches/mpfr/3.0.0/180-macros.patch
new file mode 100644
index 0000000..58a490f
--- /dev/null
+++ b/patches/mpfr/3.0.0/180-macros.patch
@@ -0,0 +1,193 @@
+diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
+--- mpfr-3.0.0-a/PATCHES 2010-11-09 15:15:07.000000000 +0000
++++ mpfr-3.0.0-b/PATCHES 2010-11-09 15:15:07.000000000 +0000
+@@ -0,0 +1 @@
++macros
+diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
+--- mpfr-3.0.0-a/VERSION 2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0-b/VERSION 2010-11-09 15:15:07.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p7
++3.0.0-p8
+diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
+--- mpfr-3.0.0-a/mpfr.h 2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0-b/mpfr.h 2010-11-09 15:15:07.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p7"
++#define MPFR_VERSION_STRING "3.0.0-p8"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -67,6 +67,16 @@
+ # define _MPFR_H_HAVE_INTMAX_T 1
+ #endif
+
++/* Avoid some problems with macro expansion if the user defines macros
++ with the same name as keywords. By convention, identifiers and macro
++ names starting with mpfr_ are reserved by MPFR. */
++typedef void mpfr_void;
++typedef int mpfr_int;
++typedef unsigned int mpfr_uint;
++typedef long mpfr_long;
++typedef unsigned long mpfr_ulong;
++typedef size_t mpfr_size_t;
++
+ /* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
+ Warning! Changing the contents of this enum should be seen as an
+ interface change since the old and the new types are not compatible
+@@ -136,7 +146,7 @@
+ typedef mp_exp_t mpfr_exp_t;
+
+ /* Definition of the standard exponent limits */
+-#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((unsigned long) 1 << 30) - 1))
++#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1))
+ #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
+
+ /* Definition of the main structure */
+@@ -725,13 +735,13 @@
+ unexpected results with future compilers and aggressive optimisations.
+ Why not working only with signed types, using INT_MIN and LONG_MIN? */
+ #if __GMP_MP_SIZE_T_INT
+-#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+2))
+-#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+1))
+-#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+3))
++#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+2))
++#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+1))
++#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+3))
+ #else
+-#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+2))
+-#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+1))
+-#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+3))
++#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+2))
++#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+1))
++#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+3))
+ #endif
+
+ /* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */
+@@ -760,9 +770,9 @@
+ #define mpfr_inf_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_INF)
+ #define mpfr_zero_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_ZERO)
+ #define mpfr_regular_p(_x) ((_x)->_mpfr_exp > __MPFR_EXP_INF)
+-#define mpfr_sgn(_x) \
+- ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \
+- (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (void) 0), 0 : \
++#define mpfr_sgn(_x) \
++ ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \
++ (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \
+ MPFR_SIGN (_x))
+
+ /* Prevent them from using as lvalues */
+@@ -805,7 +815,19 @@
+ Moreover casts to unsigned long have been added to avoid warnings in
+ programs that use MPFR and are compiled with -Wconversion; such casts
+ are OK since if X is a constant expression, then (unsigned long) X is
+- also a constant expression, so that the optimizations still work. */
++ also a constant expression, so that the optimizations still work. The
++ warnings are probably related to the following two bugs:
++ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
++ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
++ and the casts could be removed once these bugs are fixed.
++ Casts shouldn't be used on the generic calls (to the ..._2exp functions),
++ where implicit conversions are performed. Indeed, having at least one
++ implicit conversion in the macro allows the compiler to emit diagnostics
++ when normally expected, for instance in the following call:
++ mpfr_set_ui (x, "foo", MPFR_RNDN);
++ If this is not possible (for future macros), one of the tricks described
++ on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could
++ be used. */
+ #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
+ #if (__GNUC__ >= 2)
+ #undef mpfr_cmp_ui
+@@ -813,45 +835,45 @@
+ But warning! mpfr_sgn is specified as a macro in the API, thus the macro
+ mustn't be used if side effects are possible, like here. */
+ #define mpfr_cmp_ui(_f,_u) \
+- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
++ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
+ (mpfr_sgn) (_f) : \
+- mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
++ mpfr_cmp_ui_2exp ((_f), (_u), 0))
+ #undef mpfr_cmp_si
+-#define mpfr_cmp_si(_f,_s) \
+- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
+- mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \
+- mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
++#define mpfr_cmp_si(_f,_s) \
++ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
++ mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \
++ mpfr_cmp_si_2exp ((_f), (_s), 0))
+ #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
+ #undef mpfr_set_ui
+ #define mpfr_set_ui(_f,_u,_r) \
+- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
++ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
+ __extension__ ({ \
+ mpfr_ptr _p = (_f); \
+ _p->_mpfr_sign = 1; \
+ _p->_mpfr_exp = __MPFR_EXP_ZERO; \
+- (void) (_r); 0; }) : \
+- mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
++ (mpfr_void) (_r); 0; }) : \
++ mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
+ #endif
+ #undef mpfr_set_si
+ #define mpfr_set_si(_f,_s,_r) \
+- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
+- mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \
+- mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
++ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
++ mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
++ mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
+ #endif
+ #endif
+
+ /* Macro version of mpfr_stack interface for fast access */
+-#define mpfr_custom_get_size(p) ((size_t) \
++#define mpfr_custom_get_size(p) ((mpfr_size_t) \
+ (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t)))
+ #define mpfr_custom_init(m,p) do {} while (0)
+-#define mpfr_custom_get_significand(x) ((void*)((x)->_mpfr_d))
++#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d))
+ #define mpfr_custom_get_exp(x) ((x)->_mpfr_exp)
+ #define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0)
+ #define mpfr_custom_init_set(x,k,e,p,m) do { \
+ mpfr_ptr _x = (x); \
+ mpfr_exp_t _e; \
+ mpfr_kind_t _t; \
+- int _s, _k; \
++ mpfr_int _s, _k; \
+ _k = (k); \
+ if (_k >= 0) { \
+ _t = (mpfr_kind_t) _k; \
+@@ -868,11 +890,13 @@
+ _x->_mpfr_exp = _e; \
+ _x->_mpfr_d = (mp_limb_t*) (m); \
+ } while (0)
+-#define mpfr_custom_get_kind(x) \
+- ( (x)->_mpfr_exp > __MPFR_EXP_INF ? (int)MPFR_REGULAR_KIND*MPFR_SIGN (x) \
+- : (x)->_mpfr_exp == __MPFR_EXP_INF ? (int)MPFR_INF_KIND*MPFR_SIGN (x) \
+- : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (int)MPFR_NAN_KIND \
+- : (int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
++#define mpfr_custom_get_kind(x) \
++ ( (x)->_mpfr_exp > __MPFR_EXP_INF ? \
++ (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x) \
++ : (x)->_mpfr_exp == __MPFR_EXP_INF ? \
++ (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x) \
++ : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND \
++ : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
+
+
+ #endif /* MPFR_USE_NO_MACRO */
+diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
+--- mpfr-3.0.0-a/version.c 2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0-b/version.c 2010-11-09 15:15:07.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.0-p7";
++ return "3.0.0-p8";
+ }
diff --git a/patches/mpfr/3.0.1/110-asin_exprange.patch b/patches/mpfr/3.0.1/110-asin_exprange.patch
new file mode 100644
index 0000000..d79a6f9
--- /dev/null
+++ b/patches/mpfr/3.0.1/110-asin_exprange.patch
@@ -0,0 +1,137 @@
+diff -Naurd mpfr-3.0.1-a/PATCHES mpfr-3.0.1-b/PATCHES
+--- mpfr-3.0.1-a/PATCHES 2011-04-12 10:50:02.000000000 +0000
++++ mpfr-3.0.1-b/PATCHES 2011-04-12 10:50:02.000000000 +0000
+@@ -0,0 +1 @@
++asin_exprange
+diff -Naurd mpfr-3.0.1-a/VERSION mpfr-3.0.1-b/VERSION
+--- mpfr-3.0.1-a/VERSION 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/VERSION 2011-04-12 10:50:02.000000000 +0000
+@@ -1 +1 @@
+-3.0.1
++3.0.1-p1
+diff -Naurd mpfr-3.0.1-a/asin.c mpfr-3.0.1-b/asin.c
+--- mpfr-3.0.1-a/asin.c 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/asin.c 2011-04-12 10:50:02.000000000 +0000
+@@ -63,11 +63,14 @@
+
+ compared = mpfr_cmp_ui (xp, 1);
+
++ MPFR_SAVE_EXPO_MARK (expo);
++
+ if (MPFR_UNLIKELY (compared >= 0))
+ {
+ mpfr_clear (xp);
+ if (compared > 0) /* asin(x) = NaN for |x| > 1 */
+ {
++ MPFR_SAVE_EXPO_FREE (expo);
+ MPFR_SET_NAN (asin);
+ MPFR_RET_NAN;
+ }
+@@ -80,13 +83,11 @@
+ inexact = -mpfr_const_pi (asin, MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN (asin);
+ }
+- mpfr_div_2ui (asin, asin, 1, rnd_mode); /* May underflow */
+- return inexact;
++ mpfr_div_2ui (asin, asin, 1, rnd_mode);
+ }
+ }
+-
+- MPFR_SAVE_EXPO_MARK (expo);
+-
++ else
++ {
+ /* Compute exponent of 1 - ABS(x) */
+ mpfr_ui_sub (xp, 1, xp, MPFR_RNDD);
+ MPFR_ASSERTD (MPFR_GET_EXP (xp) <= 0);
+@@ -115,6 +116,7 @@
+ inexact = mpfr_set (asin, xp, rnd_mode);
+
+ mpfr_clear (xp);
++ }
+
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (asin, inexact, rnd_mode);
+diff -Naurd mpfr-3.0.1-a/mpfr.h mpfr-3.0.1-b/mpfr.h
+--- mpfr-3.0.1-a/mpfr.h 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/mpfr.h 2011-04-12 10:50:02.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.0.1"
++#define MPFR_VERSION_STRING "3.0.1-p1"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.1-a/tests/tasin.c mpfr-3.0.1-b/tests/tasin.c
+--- mpfr-3.0.1-a/tests/tasin.c 2011-04-04 10:19:17.000000000 +0000
++++ mpfr-3.0.1-b/tests/tasin.c 2011-04-12 10:50:02.000000000 +0000
+@@ -219,6 +219,49 @@
+ mpfr_clear (y);
+ }
+
++static void
++reduced_expo_range (void)
++{
++ mpfr_exp_t emin, emax;
++ mpfr_t x, y, ex_y;
++ int inex, ex_inex;
++ unsigned int flags, ex_flags;
++
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++
++ mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0);
++ mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN);
++
++ mpfr_set_emin (1);
++ mpfr_set_emax (1);
++ mpfr_clear_flags ();
++ inex = mpfr_asin (y, x, MPFR_RNDA);
++ flags = __gmpfr_flags;
++ mpfr_set_emin (emin);
++ mpfr_set_emax (emax);
++
++ mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN);
++ ex_inex = -1;
++ ex_flags = MPFR_FLAGS_INEXACT;
++
++ if (SIGN (inex) != ex_inex || flags != ex_flags ||
++ ! mpfr_equal_p (y, ex_y))
++ {
++ printf ("Error in reduced_expo_range\non x = ");
++ mpfr_dump (x);
++ printf ("Expected y = ");
++ mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
++ printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
++ printf ("Got y = ");
++ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
++ printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags);
++ exit (1);
++ }
++
++ mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
++}
++
+ int
+ main (void)
+ {
+@@ -226,6 +269,7 @@
+
+ special ();
+ special_overflow ();
++ reduced_expo_range ();
+
+ test_generic (2, 100, 15);
+
+diff -Naurd mpfr-3.0.1-a/version.c mpfr-3.0.1-b/version.c
+--- mpfr-3.0.1-a/version.c 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/version.c 2011-04-12 10:50:02.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.1";
++ return "3.0.1-p1";
+ }
diff --git a/patches/mpfr/3.0.1/120-rec_sqrt-carry.patch b/patches/mpfr/3.0.1/120-rec_sqrt-carry.patch
new file mode 100644
index 0000000..0367d84
--- /dev/null
+++ b/patches/mpfr/3.0.1/120-rec_sqrt-carry.patch
@@ -0,0 +1,76 @@
+diff -Naurd mpfr-3.0.1-a/PATCHES mpfr-3.0.1-b/PATCHES
+--- mpfr-3.0.1-a/PATCHES 2011-05-04 11:18:33.000000000 +0000
++++ mpfr-3.0.1-b/PATCHES 2011-05-04 11:18:33.000000000 +0000
+@@ -0,0 +1 @@
++rec_sqrt-carry
+diff -Naurd mpfr-3.0.1-a/VERSION mpfr-3.0.1-b/VERSION
+--- mpfr-3.0.1-a/VERSION 2011-04-12 10:50:02.000000000 +0000
++++ mpfr-3.0.1-b/VERSION 2011-05-04 11:18:33.000000000 +0000
+@@ -1 +1 @@
+-3.0.1-p1
++3.0.1-p2
+diff -Naurd mpfr-3.0.1-a/mpfr.h mpfr-3.0.1-b/mpfr.h
+--- mpfr-3.0.1-a/mpfr.h 2011-04-12 10:50:02.000000000 +0000
++++ mpfr-3.0.1-b/mpfr.h 2011-05-04 11:18:33.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.0.1-p1"
++#define MPFR_VERSION_STRING "3.0.1-p2"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.1-a/rec_sqrt.c mpfr-3.0.1-b/rec_sqrt.c
+--- mpfr-3.0.1-a/rec_sqrt.c 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/rec_sqrt.c 2011-05-04 11:18:33.000000000 +0000
+@@ -375,20 +375,37 @@
+ MPFR_ASSERTD(un == ln + 1 || un == ln + 2);
+ /* the high un-ln limbs of u will overlap the low part of {x+ln,xn},
+ we need to add or subtract the overlapping part {u + ln, un - ln} */
++ /* Warning! th may be 0, in which case the mpn_add_1 and mpn_sub_1
++ below (with size = th) mustn't be used. In such a case, the limb
++ (carry) will be 0, so that this is semantically a no-op, but if
++ mpn_add_1 and mpn_sub_1 are used, GMP (currently) still does a
++ non-atomic read/write in a place that is not always allocated,
++ with the possible consequences: a crash if the corresponding
++ address is not mapped, or (rather unlikely) memory corruption
++ if another process/thread writes at the same place; things may
++ be worse with future GMP versions. Hence the tests carry != 0. */
+ if (neg == 0)
+ {
+ if (ln > 0)
+ MPN_COPY (x, u, ln);
+ cy = mpn_add (x + ln, x + ln, xn, u + ln, un - ln);
+ /* add cu at x+un */
+- cy += mpn_add_1 (x + un, x + un, th, cu);
++ if (cu != 0)
++ {
++ MPFR_ASSERTD (th != 0);
++ cy += mpn_add_1 (x + un, x + un, th, cu);
++ }
+ }
+ else /* negative case */
+ {
+ /* subtract {u+ln, un-ln} from {x+ln,un} */
+ cy = mpn_sub (x + ln, x + ln, xn, u + ln, un - ln);
+ /* carry cy is at x+un, like cu */
+- cy = mpn_sub_1 (x + un, x + un, th, cy + cu); /* n - un = th */
++ if (cy + cu != 0)
++ {
++ MPFR_ASSERTD (th != 0);
++ cy = mpn_sub_1 (x + un, x + un, th, cy + cu); /* n - un = th */
++ }
+ /* cy cannot be zero, since the most significant bit of Xh is 1,
+ and the correction is bounded by 2^{-h+3} */
+ MPFR_ASSERTD(cy == 0);
+diff -Naurd mpfr-3.0.1-a/version.c mpfr-3.0.1-b/version.c
+--- mpfr-3.0.1-a/version.c 2011-04-12 10:50:02.000000000 +0000
++++ mpfr-3.0.1-b/version.c 2011-05-04 11:18:33.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.1-p1";
++ return "3.0.1-p2";
+ }
diff --git a/patches/mpfr/3.0.1/130-atan-expo-range.patch b/patches/mpfr/3.0.1/130-atan-expo-range.patch
new file mode 100644
index 0000000..251b837
--- /dev/null
+++ b/patches/mpfr/3.0.1/130-atan-expo-range.patch
@@ -0,0 +1,107 @@
+diff -Naurd mpfr-3.0.1-a/PATCHES mpfr-3.0.1-b/PATCHES
+--- mpfr-3.0.1-a/PATCHES 2011-05-05 00:00:35.000000000 +0000
++++ mpfr-3.0.1-b/PATCHES 2011-05-05 00:00:35.000000000 +0000
+@@ -0,0 +1 @@
++atan-expo-range
+diff -Naurd mpfr-3.0.1-a/VERSION mpfr-3.0.1-b/VERSION
+--- mpfr-3.0.1-a/VERSION 2011-05-04 11:18:33.000000000 +0000
++++ mpfr-3.0.1-b/VERSION 2011-05-05 00:00:35.000000000 +0000
+@@ -1 +1 @@
+-3.0.1-p2
++3.0.1-p3
+diff -Naurd mpfr-3.0.1-a/atan.c mpfr-3.0.1-b/atan.c
+--- mpfr-3.0.1-a/atan.c 2011-04-04 10:19:18.000000000 +0000
++++ mpfr-3.0.1-b/atan.c 2011-05-05 00:00:35.000000000 +0000
+@@ -431,5 +431,5 @@
+ MPFR_GROUP_CLEAR (group);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+- return mpfr_check_range (arctgt, inexact, rnd_mode);
++ return mpfr_check_range (atan, inexact, rnd_mode);
+ }
+diff -Naurd mpfr-3.0.1-a/mpfr.h mpfr-3.0.1-b/mpfr.h
+--- mpfr-3.0.1-a/mpfr.h 2011-05-04 11:18:33.000000000 +0000
++++ mpfr-3.0.1-b/mpfr.h 2011-05-05 00:00:35.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.0.1-p2"
++#define MPFR_VERSION_STRING "3.0.1-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.1-a/tests/tatan.c mpfr-3.0.1-b/tests/tatan.c
+--- mpfr-3.0.1-a/tests/tatan.c 2011-04-04 10:19:17.000000000 +0000
++++ mpfr-3.0.1-b/tests/tatan.c 2011-05-05 00:00:35.000000000 +0000
+@@ -535,6 +535,52 @@
+ mpfr_clears (a, x, y, (mpfr_ptr) 0);
+ }
+
++/* http://websympa.loria.fr/wwsympa/arc/mpfr/2011-05/msg00008.html
++ * Incorrect flags (in debug mode on a 32-bit machine, assertion failure).
++ */
++static void
++reduced_expo_range (void)
++{
++ mpfr_exp_t emin, emax;
++ mpfr_t x, y, ex_y;
++ int inex, ex_inex;
++ unsigned int flags, ex_flags;
++
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++
++ mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0);
++ mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN);
++
++ mpfr_set_emin (-5);
++ mpfr_set_emax (-5);
++ mpfr_clear_flags ();
++ inex = mpfr_atan (y, x, MPFR_RNDN);
++ flags = __gmpfr_flags;
++ mpfr_set_emin (emin);
++ mpfr_set_emax (emax);
++
++ mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN);
++ ex_inex = 1;
++ ex_flags = MPFR_FLAGS_INEXACT;
++
++ if (SIGN (inex) != ex_inex || flags != ex_flags ||
++ ! mpfr_equal_p (y, ex_y))
++ {
++ printf ("Error in reduced_expo_range\non x = ");
++ mpfr_dump (x);
++ printf ("Expected y = ");
++ mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
++ printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
++ printf ("Got y = ");
++ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
++ printf ("\n inex = %d, flags = %u\n", SIGN (inex), flags);
++ exit (1);
++ }
++
++ mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -546,6 +592,7 @@
+ smallvals_atan2 ();
+ atan2_bug_20071003 ();
+ atan2_different_prec ();
++ reduced_expo_range ();
+
+ test_generic_atan (2, 200, 17);
+ test_generic_atan2 (2, 200, 17);
+diff -Naurd mpfr-3.0.1-a/version.c mpfr-3.0.1-b/version.c
+--- mpfr-3.0.1-a/version.c 2011-05-04 11:18:33.000000000 +0000
++++ mpfr-3.0.1-b/version.c 2011-05-05 00:00:35.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.1-p2";
++ return "3.0.1-p3";
+ }
diff --git a/patches/mpfr/3.0.1/140-texp-zero.patch b/patches/mpfr/3.0.1/140-texp-zero.patch
new file mode 100644
index 0000000..fd74087
--- /dev/null
+++ b/patches/mpfr/3.0.1/140-texp-zero.patch
@@ -0,0 +1,47 @@
+diff -Naurd mpfr-3.0.1-a/PATCHES mpfr-3.0.1-b/PATCHES
+--- mpfr-3.0.1-a/PATCHES 2011-05-09 14:48:24.000000000 +0000
++++ mpfr-3.0.1-b/PATCHES 2011-05-09 14:48:24.000000000 +0000
+@@ -0,0 +1 @@
++texp-zero
+diff -Naurd mpfr-3.0.1-a/VERSION mpfr-3.0.1-b/VERSION
+--- mpfr-3.0.1-a/VERSION 2011-05-05 00:00:35.000000000 +0000
++++ mpfr-3.0.1-b/VERSION 2011-05-09 14:48:24.000000000 +0000
+@@ -1 +1 @@
+-3.0.1-p3
++3.0.1-p4
+diff -Naurd mpfr-3.0.1-a/mpfr.h mpfr-3.0.1-b/mpfr.h
+--- mpfr-3.0.1-a/mpfr.h 2011-05-05 00:00:35.000000000 +0000
++++ mpfr-3.0.1-b/mpfr.h 2011-05-09 14:48:24.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.0.1-p3"
++#define MPFR_VERSION_STRING "3.0.1-p4"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.1-a/tests/texp.c mpfr-3.0.1-b/tests/texp.c
+--- mpfr-3.0.1-a/tests/texp.c 2011-04-04 10:19:17.000000000 +0000
++++ mpfr-3.0.1-b/tests/texp.c 2011-05-09 14:48:24.000000000 +0000
+@@ -170,7 +170,9 @@
+ mpfr_set_prec (x, prec);
+ mpfr_set_prec (y, prec);
+ mpfr_set_prec (z, prec);
+- mpfr_urandomb (x, RANDS);
++ do
++ mpfr_urandomb (x, RANDS);
++ while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */
+ rnd = RND_RAND ();
+ mpfr_exp_2 (y, x, rnd);
+ mpfr_exp_3 (z, x, rnd);
+diff -Naurd mpfr-3.0.1-a/version.c mpfr-3.0.1-b/version.c
+--- mpfr-3.0.1-a/version.c 2011-05-05 00:00:35.000000000 +0000
++++ mpfr-3.0.1-b/version.c 2011-05-09 14:48:24.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.0.1-p3";
++ return "3.0.1-p4";
+ }
diff --git a/patches/mpfr/3.1.0/110-mpfr_unlikely.patch b/patches/mpfr/3.1.0/110-mpfr_unlikely.patch
new file mode 100644
index 0000000..437b1a2
--- /dev/null
+++ b/patches/mpfr/3.1.0/110-mpfr_unlikely.patch
@@ -0,0 +1,50 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2011-10-05 21:39:57.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2011-10-05 21:39:57.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_unlikely
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2011-10-03 08:17:15.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2011-10-05 21:39:57.000000000 +0000
+@@ -1 +1 @@
+-3.1.0
++3.1.0-p1
+diff -Naurd mpfr-3.1.0-a/src/mpfr-impl.h mpfr-3.1.0-b/src/mpfr-impl.h
+--- mpfr-3.1.0-a/src/mpfr-impl.h 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr-impl.h 2011-10-05 21:39:57.000000000 +0000
+@@ -988,10 +988,11 @@
+ ******************************************************/
+
+ /* Theses macros help the compiler to determine if a test is
+- * likely or unlikely. */
++ likely or unlikely. The !! is necessary in case x is larger
++ than a long. */
+ #if __MPFR_GNUC(3,0) || __MPFR_ICC(8,1,0)
+ # define MPFR_LIKELY(x) (__builtin_expect(!!(x),1))
+-# define MPFR_UNLIKELY(x) (__builtin_expect((x),0))
++# define MPFR_UNLIKELY(x) (__builtin_expect(!!(x),0))
+ #else
+ # define MPFR_LIKELY(x) (x)
+ # define MPFR_UNLIKELY(x) (x)
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2011-10-05 21:39:57.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0"
++#define MPFR_VERSION_STRING "3.1.0-p1"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2011-10-05 21:39:57.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0";
++ return "3.1.0-p1";
+ }
diff --git a/patches/mpfr/3.1.0/120-lib-search-path.patch b/patches/mpfr/3.1.0/120-lib-search-path.patch
new file mode 100644
index 0000000..4714ac9
--- /dev/null
+++ b/patches/mpfr/3.1.0/120-lib-search-path.patch
@@ -0,0 +1,96 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2011-10-14 10:43:32.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2011-10-14 10:43:32.000000000 +0000
+@@ -0,0 +1 @@
++lib-search-path
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2011-10-05 21:39:57.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2011-10-14 10:43:32.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p1
++3.1.0-p2
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2011-10-05 21:39:57.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2011-10-14 10:43:32.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p1"
++#define MPFR_VERSION_STRING "3.1.0-p2"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2011-10-05 21:39:57.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2011-10-14 10:43:32.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p1";
++ return "3.1.0-p2";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/Makefile.am mpfr-3.1.0-b/tests/Makefile.am
+--- mpfr-3.1.0-a/tests/Makefile.am 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/Makefile.am 2011-10-03 08:17:14.000000000 +0000
+@@ -65,8 +65,24 @@
+ TESTS = $(check_PROGRAMS)
+ TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND)
+
+-# Option to prevent libtool from generating wrapper scripts for the tests.
++# The -no-install option prevents libtool from generating wrapper scripts
++# for the tests.
+ # This is useful to easily run the test scripts under valgrind or gdb.
+ # See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033
+ # http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular.
+-AM_LDFLAGS = -no-install
++#
++# The -L$(top_builddir)/src/.libs option is necessary for some platforms,
++# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR
++# library is already installed in the corresponding lib directory: its
++# purpose is to make sure that the local .libs comes first in the library
++# search path (otherwise the tests are linked against the old MPFR library
++# by the LINK command -- see the generated Makefile). See:
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00042.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00043.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00044.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00066.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00065.html
++# and
++# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728
++#
++AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs
+diff -Naurd mpfr-3.1.0-a/tests/Makefile.in mpfr-3.1.0-b/tests/Makefile.in
+--- mpfr-3.1.0-a/tests/Makefile.in 2011-10-03 08:17:35.000000000 +0000
++++ mpfr-3.1.0-b/tests/Makefile.in 2011-10-03 08:17:35.000000000 +0000
+@@ -1124,11 +1124,27 @@
+ TESTS = $(check_PROGRAMS)
+ TESTS_ENVIRONMENT = MPFR_QUIET=1 $(VALGRIND)
+
+-# Option to prevent libtool from generating wrapper scripts for the tests.
++# The -no-install option prevents libtool from generating wrapper scripts
++# for the tests.
+ # This is useful to easily run the test scripts under valgrind or gdb.
+ # See discussion http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/28033
+ # http://article.gmane.org/gmane.comp.lib.gnulib.bugs/28140 in particular.
+-AM_LDFLAGS = -no-install
++#
++# The -L$(top_builddir)/src/.libs option is necessary for some platforms,
++# such as HP-UX, when --with-gmp or --with-gmp-lib is used and an old MPFR
++# library is already installed in the corresponding lib directory: its
++# purpose is to make sure that the local .libs comes first in the library
++# search path (otherwise the tests are linked against the old MPFR library
++# by the LINK command -- see the generated Makefile). See:
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00042.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00043.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00044.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00066.html
++# http://websympa.loria.fr/wwsympa/arc/mpfr/2011-10/msg00065.html
++# and
++# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9728
++#
++AM_LDFLAGS = -no-install -L$(top_builddir)/src/.libs
+ all: all-am
+
+ .SUFFIXES:
diff --git a/patches/mpfr/3.1.0/130-vasprintf.patch b/patches/mpfr/3.1.0/130-vasprintf.patch
new file mode 100644
index 0000000..aa1cfbc
--- /dev/null
+++ b/patches/mpfr/3.1.0/130-vasprintf.patch
@@ -0,0 +1,247 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2011-11-03 15:15:11.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2011-11-03 15:15:11.000000000 +0000
+@@ -0,0 +1 @@
++vasprintf
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2011-10-14 10:43:32.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2011-11-03 15:15:11.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p2
++3.1.0-p3
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2011-10-14 10:43:32.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2011-11-03 15:15:11.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p2"
++#define MPFR_VERSION_STRING "3.1.0-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/vasprintf.c mpfr-3.1.0-b/src/vasprintf.c
+--- mpfr-3.1.0-a/src/vasprintf.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/vasprintf.c 2011-11-03 15:15:11.000000000 +0000
+@@ -1178,7 +1178,7 @@
+ mpfr_exp_t exp;
+ char * str;
+ const int spec_g = (spec.spec == 'g' || spec.spec == 'G');
+- const int keep_trailing_zeros = spec_g && spec.alt;
++ const int keep_trailing_zeros = !spec_g || spec.alt;
+
+ /* WARNING: an empty precision field is forbidden (it means precision = 6
+ and it should have been changed to 6 before the function call) */
+@@ -1356,7 +1356,7 @@
+ else
+ /* 1 <= |p| */
+ {
+- size_t nsd; /* Number of significant digits */
++ size_t str_len;
+
+ /* Determine the position of the most significant decimal digit. */
+ exp = floor_log10 (p);
+@@ -1365,12 +1365,10 @@
+ /* P is too large to print all its integral part digits */
+ return -1;
+
+- np->ip_size = exp + 1;
+-
+- nsd = spec.prec + np->ip_size;
+ if (dec_info == NULL)
+- {
+- str = mpfr_get_str (NULL, &exp, 10, nsd, p, spec.rnd_mode);
++ { /* this case occurs with mpfr_printf ("%.0RUf", x) with x=9.5 */
++ str =
++ mpfr_get_str (NULL, &exp, 10, spec.prec+exp+1, p, spec.rnd_mode);
+ register_string (np->sl, str);
+ }
+ else
+@@ -1379,81 +1377,60 @@
+ str = dec_info->str;
+ }
+ np->ip_ptr = MPFR_IS_NEG (p) ? ++str : str; /* skip sign */
++ str_len = strlen (str);
++
++ /* integral part */
++ if (exp > str_len)
++ /* mpfr_get_str gives no trailing zero when p is rounded up to the next
++ power of 10 (p integer, so no fractional part) */
++ {
++ np->ip_trailing_zeros = exp - str_len;
++ np->ip_size = str_len;
++ }
++ else
++ np->ip_size = exp;
+
+ if (spec.group)
+ /* thousands separator in integral part */
+ np->thousands_sep = MPFR_THOUSANDS_SEPARATOR;
+
+- if (nsd == 0 || (spec_g && !spec.alt))
+- /* compute how much non-zero digits in integral and fractional
+- parts */
++ /* fractional part */
++ str += np->ip_size;
++ str_len -= np->ip_size;
++ if (!keep_trailing_zeros)
++ /* remove trailing zeros, if any */
+ {
+- size_t str_len;
+- str_len = strlen (str); /* note: the sign has been skipped */
+-
+- if (exp > str_len)
+- /* mpfr_get_str doesn't give the trailing zeros when p is a
+- multiple of 10 (p integer, so no fractional part) */
+- {
+- np->ip_trailing_zeros = exp - str_len;
+- np->ip_size = str_len;
+- if (spec.alt)
+- np->point = MPFR_DECIMAL_POINT;
+- }
+- else
+- /* str may contain some digits which are in fractional part */
++ char *ptr = str + str_len - 1; /* pointer to the last digit of
++ str */
++ while ((*ptr == '0') && (str_len != 0))
+ {
+- char *ptr;
+-
+- ptr = str + str_len - 1; /* points to the end of str */
+- str_len -= np->ip_size; /* number of digits in fractional
+- part */
+-
+- if (!keep_trailing_zeros)
+- /* remove trailing zeros, if any */
+- {
+- while ((*ptr == '0') && (str_len != 0))
+- {
+- --ptr;
+- --str_len;
+- }
+- }
+-
+- if (str_len > INT_MAX)
+- /* too many digits in fractional part */
+- return -1;
+-
+- if (str_len != 0)
+- /* some digits in fractional part */
+- {
+- np->point = MPFR_DECIMAL_POINT;
+- np->fp_ptr = str + np->ip_size;
+- np->fp_size = str_len;
+- }
++ --ptr;
++ --str_len;
+ }
+ }
+- else
+- /* spec.prec digits in fractional part */
++
++ if (str_len > 0)
++ /* some nonzero digits in fractional part */
+ {
+- if (np->ip_size == exp - 1)
+- /* the absolute value of the number has been rounded up to a power
+- of ten.
+- Insert an additional zero in integral part and put the rest of
+- them in fractional part. */
+- np->ip_trailing_zeros = 1;
++ if (str_len > INT_MAX)
++ /* too many digits in fractional part */
++ return -1;
+
+- if (spec.prec != 0)
+- {
+- MPFR_ASSERTD (np->ip_size + np->ip_trailing_zeros == exp);
+- MPFR_ASSERTD (np->ip_size + spec.prec == nsd);
++ np->point = MPFR_DECIMAL_POINT;
++ np->fp_ptr = str;
++ np->fp_size = str_len;
++ }
+
+- np->point = MPFR_DECIMAL_POINT;
+- np->fp_ptr = str + np->ip_size;
+- np->fp_size = spec.prec;
+- }
+- else if (spec.alt)
+- np->point = MPFR_DECIMAL_POINT;
++ if (keep_trailing_zeros && str_len < spec.prec)
++ /* add missing trailing zeros */
++ {
++ np->point = MPFR_DECIMAL_POINT;
++ np->fp_trailing_zeros = spec.prec - np->fp_size;
+ }
++
++ if (spec.alt)
++ /* add decimal point even if no digits follow it */
++ np->point = MPFR_DECIMAL_POINT;
+ }
+
+ return 0;
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2011-10-14 10:43:32.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2011-11-03 15:15:11.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p2";
++ return "3.1.0-p3";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/tsprintf.c mpfr-3.1.0-b/tests/tsprintf.c
+--- mpfr-3.1.0-a/tests/tsprintf.c 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/tsprintf.c 2011-11-03 15:15:11.000000000 +0000
+@@ -475,6 +475,18 @@
+ check_sprintf ("-1.", "%- #0.1RG", x);
+
+ /* precision zero */
++ mpfr_set_d (x, 9.5, MPFR_RNDN);
++ check_sprintf ("9", "%.0RDf", x);
++ check_sprintf ("10", "%.0RUf", x);
++
++ mpfr_set_d (x, 19.5, MPFR_RNDN);
++ check_sprintf ("19", "%.0RDf", x);
++ check_sprintf ("20", "%.0RUf", x);
++
++ mpfr_set_d (x, 99.5, MPFR_RNDN);
++ check_sprintf ("99", "%.0RDf", x);
++ check_sprintf ("100", "%.0RUf", x);
++
+ mpfr_set_d (x, -9.5, MPFR_RNDN);
+ check_sprintf ("-10", "%.0RDf", x);
+ check_sprintf ("-10", "%.0RYf", x);
+@@ -1078,6 +1090,23 @@
+ mpfr_clear (x);
+ }
+
++static void
++bug20111102 (void)
++{
++ mpfr_t t;
++ char s[100];
++
++ mpfr_init2 (t, 84);
++ mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN);
++ mpfr_sprintf (s, "%.20RNg", t);
++ if (strcmp (s, "1000") != 0)
++ {
++ printf ("Error in bug20111102, expected 1000, got %s\n", s);
++ exit (1);
++ }
++ mpfr_clear (t);
++}
++
+ /* In particular, the following test makes sure that the rounding
+ * for %Ra and %Rb is not done on the MPFR number itself (as it
+ * would overflow). Note: it has been reported on comp.std.c that
+@@ -1161,6 +1190,7 @@
+ locale = setlocale (LC_ALL, "C");
+ #endif
+
++ bug20111102 ();
+ native_types ();
+ hexadecimal ();
+ binary ();
diff --git a/patches/mpfr/3.1.0/140-gmp41compat.patch b/patches/mpfr/3.1.0/140-gmp41compat.patch
new file mode 100644
index 0000000..4b1ba08
--- /dev/null
+++ b/patches/mpfr/3.1.0/140-gmp41compat.patch
@@ -0,0 +1,166 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2011-11-28 12:22:52.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2011-11-28 12:22:52.000000000 +0000
+@@ -0,0 +1 @@
++gmp41compat
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2011-11-03 15:15:11.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2011-11-28 12:22:52.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p3
++3.1.0-p4
+diff -Naurd mpfr-3.1.0-a/doc/mpfr.info mpfr-3.1.0-b/doc/mpfr.info
+--- mpfr-3.1.0-a/doc/mpfr.info 2011-10-03 09:43:04.000000000 +0000
++++ mpfr-3.1.0-b/doc/mpfr.info 2011-11-28 12:22:52.000000000 +0000
+@@ -2994,11 +2994,12 @@
+
+ * `mpfr_urandom' and `mpfr_urandomb' changed in MPFR 3.1. Their
+ behavior no longer depends on the platform (assuming this is also
+- true for GMP's random generator). As a consequence, the returned
+- values can be different between MPFR 3.1 and previous MPFR
+- versions. Note: as the reproducibility of these functions was not
+- specified before MPFR 3.1, the MPFR 3.1 behavior is _not_ regarded
+- as backward incompatible with previous versions.
++ true for GMP's random generator, which is not the case between GMP
++ 4.1 and 4.2 if `gmp_randinit_default' is used). As a consequence,
++ the returned values can be different between MPFR 3.1 and previous
++ MPFR versions. Note: as the reproducibility of these functions
++ was not specified before MPFR 3.1, the MPFR 3.1 behavior is _not_
++ regarded as backward incompatible with previous versions.
+
+
+ 
+@@ -4239,13 +4240,13 @@
+ Node: Type and Macro Changes129308
+ Node: Added Functions132029
+ Node: Changed Functions134972
+-Node: Removed Functions139167
+-Node: Other Changes139579
+-Node: Contributors141108
+-Node: References143574
+-Node: GNU Free Documentation License145315
+-Node: Concept Index167758
+-Node: Function and Type Index173677
++Node: Removed Functions139253
++Node: Other Changes139665
++Node: Contributors141194
++Node: References143660
++Node: GNU Free Documentation License145401
++Node: Concept Index167844
++Node: Function and Type Index173763
+ 
+ End Tag Table
+
+diff -Naurd mpfr-3.1.0-a/doc/mpfr.texi mpfr-3.1.0-b/doc/mpfr.texi
+--- mpfr-3.1.0-a/doc/mpfr.texi 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/doc/mpfr.texi 2011-11-28 12:22:52.000000000 +0000
+@@ -3466,8 +3466,9 @@
+ a lack of specification.
+
+ @item @code{mpfr_urandom} and @code{mpfr_urandomb} changed in MPFR 3.1.
+-Their behavior no longer depends on the platform (assuming this is also
+-true for GMP's random generator). As a consequence, the returned values
++Their behavior no longer depends on the platform (assuming this is also true
++for GMP's random generator, which is not the case between GMP 4.1 and 4.2 if
++@code{gmp_randinit_default} is used). As a consequence, the returned values
+ can be different between MPFR 3.1 and previous MPFR versions.
+ Note: as the reproducibility of these functions was not specified
+ before MPFR 3.1, the MPFR 3.1 behavior is @emph{not} regarded as
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2011-11-03 15:15:11.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2011-11-28 12:22:52.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p3"
++#define MPFR_VERSION_STRING "3.1.0-p4"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2011-11-03 15:15:11.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2011-11-28 12:22:52.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p3";
++ return "3.1.0-p4";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/trandom.c mpfr-3.1.0-b/tests/trandom.c
+--- mpfr-3.1.0-a/tests/trandom.c 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/trandom.c 2011-11-28 12:22:52.000000000 +0000
+@@ -114,21 +114,29 @@
+ mpfr_t x;
+ gmp_randstate_t s;
+
++#if __MPFR_GMP(4,2,0)
++# define C1 "0.895943"
++# define C2 "0.848824"
++#else
++# define C1 "0.479652"
++# define C2 "0.648529"
++#endif
++
+ gmp_randinit_default (s);
+ gmp_randseed_ui (s, 42);
+ mpfr_init2 (x, 17);
+ mpfr_urandomb (x, s);
+- if (mpfr_cmp_str1 (x, "0.895943") != 0)
++ if (mpfr_cmp_str1 (x, C1) != 0)
+ {
+- printf ("Error in bug20100914, expected 0.895943, got ");
++ printf ("Error in bug20100914, expected " C1 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_urandomb (x, s);
+- if (mpfr_cmp_str1 (x, "0.848824") != 0)
++ if (mpfr_cmp_str1 (x, C2) != 0)
+ {
+- printf ("Error in bug20100914, expected 0.848824, got ");
++ printf ("Error in bug20100914, expected " C2 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+diff -Naurd mpfr-3.1.0-a/tests/turandom.c mpfr-3.1.0-b/tests/turandom.c
+--- mpfr-3.1.0-a/tests/turandom.c 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/turandom.c 2011-11-28 12:22:52.000000000 +0000
+@@ -160,23 +160,29 @@
+ mpfr_t x;
+ gmp_randstate_t s;
+
++#if __MPFR_GMP(4,2,0)
++# define C1 "0.8488312"
++# define C2 "0.8156509"
++#else
++# define C1 "0.6485367"
++# define C2 "0.9362717"
++#endif
++
+ gmp_randinit_default (s);
+ gmp_randseed_ui (s, 42);
+ mpfr_init2 (x, 17);
+ mpfr_urandom (x, s, MPFR_RNDN);
+- /* the following values are obtained on a 32-bit computer, we should get
+- the same values on a 64-bit computer */
+- if (mpfr_cmp_str1 (x, "0.8488312") != 0)
++ if (mpfr_cmp_str1 (x, C1) != 0)
+ {
+- printf ("Error in bug20100914, expected 0.8488312, got ");
++ printf ("Error in bug20100914, expected " C1 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
+ }
+ mpfr_urandom (x, s, MPFR_RNDN);
+- if (mpfr_cmp_str1 (x, "0.8156509") != 0)
++ if (mpfr_cmp_str1 (x, C2) != 0)
+ {
+- printf ("Error in bug20100914, expected 0.8156509, got ");
++ printf ("Error in bug20100914, expected " C2 ", got ");
+ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
+ printf ("\n");
+ exit (1);
diff --git a/patches/mpfr/3.1.0/150-logging-freeze.patch b/patches/mpfr/3.1.0/150-logging-freeze.patch
new file mode 100644
index 0000000..c664cee
--- /dev/null
+++ b/patches/mpfr/3.1.0/150-logging-freeze.patch
@@ -0,0 +1,69 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-02-24 12:44:49.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-02-24 12:44:49.000000000 +0000
+@@ -0,0 +1 @@
++logging-freeze
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2011-11-28 12:22:52.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-02-24 12:44:49.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p4
++3.1.0-p5
+diff -Naurd mpfr-3.1.0-a/src/add_d.c mpfr-3.1.0-b/src/add_d.c
+--- mpfr-3.1.0-a/src/add_d.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/add_d.c 2012-02-24 12:44:49.000000000 +0000
+@@ -34,7 +34,7 @@
+ (("b[%Pu]=%.*Rg c=%.20g rnd=%d",
+ mpfr_get_prec(b), mpfr_log_prec, b, c, rnd_mode),
+ ("a[%Pu]=%.*Rg inexact=%d",
+- mpfr_get_prec (a), mpfr_get_prec, a, inexact));
++ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+diff -Naurd mpfr-3.1.0-a/src/add_ui.c mpfr-3.1.0-b/src/add_ui.c
+--- mpfr-3.1.0-a/src/add_ui.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/add_ui.c 2012-02-24 12:44:49.000000000 +0000
+@@ -29,7 +29,7 @@
+ MPFR_LOG_FUNC
+ (("x[%Pu]=%.*Rg u=%d rnd=%d",
+ mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
+- ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_get_prec, y));
++ ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
+
+ if (MPFR_LIKELY(u != 0) ) /* if u=0, do nothing */
+ {
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2011-11-28 12:22:52.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-02-24 12:44:49.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p4"
++#define MPFR_VERSION_STRING "3.1.0-p5"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/mul_d.c mpfr-3.1.0-b/src/mul_d.c
+--- mpfr-3.1.0-a/src/mul_d.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/mul_d.c 2012-02-24 12:44:49.000000000 +0000
+@@ -34,7 +34,7 @@
+ (("b[%Pu]=%.*Rg c=%.20g rnd=%d",
+ mpfr_get_prec(b), mpfr_log_prec, b, c, rnd_mode),
+ ("a[%Pu]=%.*Rg inexact=%d",
+- mpfr_get_prec (a), mpfr_get_prec, a, inexact));
++ mpfr_get_prec (a), mpfr_log_prec, a, inexact));
+
+ MPFR_SAVE_EXPO_MARK (expo);
+
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2011-11-28 12:22:52.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-02-24 12:44:49.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p4";
++ return "3.1.0-p5";
+ }
diff --git a/patches/mpfr/3.1.0/160-logging-varfmt.patch b/patches/mpfr/3.1.0/160-logging-varfmt.patch
new file mode 100644
index 0000000..0f4bfad
--- /dev/null
+++ b/patches/mpfr/3.1.0/160-logging-varfmt.patch
@@ -0,0 +1,45 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-02-24 13:50:05.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-02-24 13:50:05.000000000 +0000
+@@ -0,0 +1 @@
++logging-varfmt
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2012-02-24 12:44:49.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-02-24 13:50:05.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p5
++3.1.0-p6
+diff -Naurd mpfr-3.1.0-a/src/mpfr-impl.h mpfr-3.1.0-b/src/mpfr-impl.h
+--- mpfr-3.1.0-a/src/mpfr-impl.h 2011-10-05 21:39:57.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr-impl.h 2012-02-24 13:50:05.000000000 +0000
+@@ -1592,7 +1592,7 @@
+ do \
+ if ((MPFR_LOG_INTERNAL_F & mpfr_log_type) && \
+ (mpfr_log_current <= mpfr_log_level)) \
+- LOG_PRINT ("%s.%d:%s[%#Pu]=%.*Rf\n", __func__, __LINE__, \
++ LOG_PRINT ("%s.%d:%s[%#Pu]=%.*Rg\n", __func__, __LINE__, \
+ #x, mpfr_get_prec (x), mpfr_log_prec, x); \
+ while (0)
+
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2012-02-24 12:44:49.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-02-24 13:50:05.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p5"
++#define MPFR_VERSION_STRING "3.1.0-p6"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2012-02-24 12:44:49.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-02-24 13:50:05.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p5";
++ return "3.1.0-p6";
+ }
diff --git a/patches/mpfr/3.1.0/170-large-prec.patch b/patches/mpfr/3.1.0/170-large-prec.patch
new file mode 100644
index 0000000..08e7b57
--- /dev/null
+++ b/patches/mpfr/3.1.0/170-large-prec.patch
@@ -0,0 +1,591 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-03-08 15:17:03.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-03-08 15:17:03.000000000 +0000
+@@ -0,0 +1 @@
++large-prec
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2012-02-24 13:50:05.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-03-08 15:17:03.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p6
++3.1.0-p7
+diff -Naurd mpfr-3.1.0-a/src/add1.c mpfr-3.1.0-b/src/add1.c
+--- mpfr-3.1.0-a/src/add1.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/add1.c 2012-03-08 15:17:03.000000000 +0000
+@@ -44,12 +44,12 @@
+ bq = MPFR_PREC(b);
+ cq = MPFR_PREC(c);
+
+- an = (aq-1)/GMP_NUMB_BITS+1; /* number of limbs of a */
++ an = MPFR_PREC2LIMBS (aq); /* number of limbs of a */
+ aq2 = (mpfr_prec_t) an * GMP_NUMB_BITS;
+ sh = aq2 - aq; /* non-significant bits in low limb */
+
+- bn = (bq-1)/GMP_NUMB_BITS+1; /* number of limbs of b */
+- cn = (cq-1)/GMP_NUMB_BITS+1; /* number of limbs of c */
++ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
++ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+
+ ap = MPFR_MANT(a);
+ bp = MPFR_MANT(b);
+@@ -124,7 +124,7 @@
+ dif = aq2 - diff_exp;
+ /* dif is the number of bits of c which overlap with a' */
+
+- difn = (dif-1)/GMP_NUMB_BITS + 1;
++ difn = MPFR_PREC2LIMBS (dif);
+ /* only the highest difn limbs from c have to be considered */
+ if (MPFR_UNLIKELY(difn > cn))
+ {
+diff -Naurd mpfr-3.1.0-a/src/add1sp.c mpfr-3.1.0-b/src/add1sp.c
+--- mpfr-3.1.0-a/src/add1sp.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/add1sp.c 2012-03-08 15:17:03.000000000 +0000
+@@ -107,7 +107,7 @@
+
+ /* Read prec and num of limbs */
+ p = MPFR_PREC(b);
+- n = (p+GMP_NUMB_BITS-1)/GMP_NUMB_BITS;
++ n = MPFR_PREC2LIMBS (p);
+ MPFR_UNSIGNED_MINUS_MODULO(sh, p);
+ bx = MPFR_GET_EXP(b);
+ d = (mpfr_uexp_t) (bx - MPFR_GET_EXP(c));
+diff -Naurd mpfr-3.1.0-a/src/agm.c mpfr-3.1.0-b/src/agm.c
+--- mpfr-3.1.0-a/src/agm.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/agm.c 2012-03-08 15:17:03.000000000 +0000
+@@ -91,7 +91,7 @@
+ q = MPFR_PREC(r);
+ p = q + MPFR_INT_CEIL_LOG2(q) + 15;
+ MPFR_ASSERTD (p >= 7); /* see algorithms.tex */
+- s = (p - 1) / GMP_NUMB_BITS + 1;
++ s = MPFR_PREC2LIMBS (p);
+
+ /* b (op2) and a (op1) are the 2 operands but we want b >= a */
+ compare = mpfr_cmp (op1, op2);
+@@ -285,7 +285,7 @@
+
+ /* Next iteration */
+ MPFR_ZIV_NEXT (loop, p);
+- s = (p - 1) / GMP_NUMB_BITS + 1;
++ s = MPFR_PREC2LIMBS (p);
+ }
+ MPFR_ZIV_FREE (loop);
+
+diff -Naurd mpfr-3.1.0-a/src/eq.c mpfr-3.1.0-b/src/eq.c
+--- mpfr-3.1.0-a/src/eq.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/eq.c 2012-03-08 15:17:03.000000000 +0000
+@@ -56,8 +56,8 @@
+ if (uexp != vexp)
+ return 0; /* no bit agree */
+
+- usize = (MPFR_PREC(u) - 1) / GMP_NUMB_BITS + 1;
+- vsize = (MPFR_PREC(v) - 1) / GMP_NUMB_BITS + 1;
++ usize = MPFR_LIMB_SIZE (u);
++ vsize = MPFR_LIMB_SIZE (v);
+
+ if (vsize > usize) /* exchange u and v */
+ {
+diff -Naurd mpfr-3.1.0-a/src/exp.c mpfr-3.1.0-b/src/exp.c
+--- mpfr-3.1.0-a/src/exp.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/exp.c 2012-03-08 15:17:03.000000000 +0000
+@@ -133,7 +133,7 @@
+ mp_size_t yn;
+ int sh;
+
+- yn = 1 + (MPFR_PREC(y) - 1) / GMP_NUMB_BITS;
++ yn = MPFR_LIMB_SIZE (y);
+ sh = (mpfr_prec_t) yn * GMP_NUMB_BITS - MPFR_PREC(y);
+ MPFR_MANT(y)[0] += MPFR_LIMB_ONE << sh;
+ inexact = 1;
+diff -Naurd mpfr-3.1.0-a/src/get_d.c mpfr-3.1.0-b/src/get_d.c
+--- mpfr-3.1.0-a/src/get_d.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/get_d.c 2012-03-08 15:17:03.000000000 +0000
+@@ -100,7 +100,7 @@
+ nbits += (1021 + e);
+ MPFR_ASSERTD (nbits >= 1);
+ }
+- np = (nbits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
++ np = MPFR_PREC2LIMBS (nbits);
+ MPFR_ASSERTD ( np <= MPFR_LIMBS_PER_DOUBLE );
+ carry = mpfr_round_raw_4 (tp, MPFR_MANT(src), MPFR_PREC(src), negative,
+ nbits, rnd_mode);
+diff -Naurd mpfr-3.1.0-a/src/get_flt.c mpfr-3.1.0-b/src/get_flt.c
+--- mpfr-3.1.0-a/src/get_flt.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/get_flt.c 2012-03-08 15:17:03.000000000 +0000
+@@ -92,7 +92,7 @@
+ nbits += (125 + e);
+ MPFR_ASSERTD (nbits >= 1);
+ }
+- np = (nbits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
++ np = MPFR_PREC2LIMBS (nbits);
+ MPFR_ASSERTD(np <= MPFR_LIMBS_PER_FLT);
+ carry = mpfr_round_raw_4 (tp, MPFR_MANT(src), MPFR_PREC(src), negative,
+ nbits, rnd_mode);
+diff -Naurd mpfr-3.1.0-a/src/get_str.c mpfr-3.1.0-b/src/get_str.c
+--- mpfr-3.1.0-a/src/get_str.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/get_str.c 2012-03-08 15:17:03.000000000 +0000
+@@ -2351,7 +2351,7 @@
+
+ /* the first digit will contain only r bits */
+ prec = (m - 1) * pow2 + r; /* total number of bits */
+- n = (prec - 1) / GMP_NUMB_BITS + 1;
++ n = MPFR_PREC2LIMBS (prec);
+
+ MPFR_TMP_MARK (marker);
+ x1 = MPFR_TMP_LIMBS_ALLOC (n + 1);
+@@ -2417,12 +2417,12 @@
+ exact = 1;
+
+ /* number of limbs */
+- n = 1 + (prec - 1) / GMP_NUMB_BITS;
++ n = MPFR_PREC2LIMBS (prec);
+
+ /* a will contain the approximation of the mantissa */
+ a = MPFR_TMP_LIMBS_ALLOC (n);
+
+- nx = 1 + (MPFR_PREC(x) - 1) / GMP_NUMB_BITS;
++ nx = MPFR_LIMB_SIZE (x);
+
+ if ((mpfr_exp_t) m == g) /* final exponent is 0, no multiplication or
+ division to perform */
+diff -Naurd mpfr-3.1.0-a/src/init2.c mpfr-3.1.0-b/src/init2.c
+--- mpfr-3.1.0-a/src/init2.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/init2.c 2012-03-08 15:17:03.000000000 +0000
+@@ -51,7 +51,7 @@
+ which both have an odd mantissa */
+ MPFR_ASSERTN(p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+
+- xsize = (mp_size_t) ((p - 1) / GMP_NUMB_BITS) + 1;
++ xsize = MPFR_PREC2LIMBS (p);
+ tmp = (mpfr_limb_ptr) (*__gmp_allocate_func)(MPFR_MALLOC_SIZE(xsize));
+
+ MPFR_PREC(x) = p; /* Set prec */
+diff -Naurd mpfr-3.1.0-a/src/lngamma.c mpfr-3.1.0-b/src/lngamma.c
+--- mpfr-3.1.0-a/src/lngamma.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/lngamma.c 2012-03-08 15:17:03.000000000 +0000
+@@ -67,7 +67,7 @@
+
+ /* Now, the unit bit is represented. */
+
+- prec = ((prec - 1) / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS - expo;
++ prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
+ /* number of represented fractional bits (including the trailing 0's) */
+
+ x0 = *(MPFR_MANT (x) + prec / GMP_NUMB_BITS);
+diff -Naurd mpfr-3.1.0-a/src/mpfr-impl.h mpfr-3.1.0-b/src/mpfr-impl.h
+--- mpfr-3.1.0-a/src/mpfr-impl.h 2012-02-24 13:50:05.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr-impl.h 2012-03-09 12:06:26.000000000 +0000
+@@ -646,10 +646,24 @@
+ **************** mpfr_t properties *******************
+ ******************************************************/
+
++/* In the following macro, p is usually a mpfr_prec_t, but this macro
++ works with other integer types (without integer overflow). Checking
++ that p >= 1 in debug mode is useful here because this macro can be
++ used on a computed precision (in particular, this formula does not
++ work for a degenerate case p = 0, and could give different results
++ on different platforms). But let us not use an assertion checking
++ in the MPFR_LAST_LIMB() and MPFR_LIMB_SIZE() macros below to avoid
++ too much expansion for assertions (in practice, this should be a
++ problem just when testing MPFR with the --enable-assert configure
++ option and the -ansi -pedantic-errors gcc compiler flags). */
++#define MPFR_PREC2LIMBS(p) \
++ (MPFR_ASSERTD ((p) >= 1), ((p) - 1) / GMP_NUMB_BITS + 1)
++
+ #define MPFR_PREC(x) ((x)->_mpfr_prec)
+ #define MPFR_EXP(x) ((x)->_mpfr_exp)
+ #define MPFR_MANT(x) ((x)->_mpfr_d)
+-#define MPFR_LIMB_SIZE(x) ((MPFR_PREC((x))-1)/GMP_NUMB_BITS+1)
++#define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
++#define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
+
+
+ /******************************************************
+@@ -749,7 +763,8 @@
+ #define MPFR_IS_FP(x) (!MPFR_IS_NAN(x) && !MPFR_IS_INF(x))
+ #define MPFR_IS_SINGULAR(x) (MPFR_EXP(x) <= MPFR_EXP_INF)
+ #define MPFR_IS_PURE_FP(x) (!MPFR_IS_SINGULAR(x) && \
+- (MPFR_ASSERTD (MPFR_MANT(x)[MPFR_LIMB_SIZE(x)-1] & MPFR_LIMB_HIGHBIT), 1))
++ (MPFR_ASSERTD ((MPFR_MANT(x)[MPFR_LAST_LIMB(x)] \
++ & MPFR_LIMB_HIGHBIT) != 0), 1))
+
+ #define MPFR_ARE_SINGULAR(x,y) \
+ (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)) || MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
+@@ -1061,7 +1076,7 @@
+ /* Set a number to 1 (Fast) - It doesn't check if 1 is in the exponent range */
+ #define MPFR_SET_ONE(x) \
+ do { \
+- mp_size_t _size = MPFR_LIMB_SIZE(x) - 1; \
++ mp_size_t _size = MPFR_LAST_LIMB(x); \
+ MPFR_SET_POS(x); \
+ MPFR_EXP(x) = 1; \
+ MPN_ZERO ( MPFR_MANT(x), _size); \
+@@ -1213,8 +1228,8 @@
+ _destp = MPFR_MANT (dest); \
+ if (MPFR_UNLIKELY (_destprec >= _srcprec)) \
+ { \
+- _srcs = (_srcprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
+- _dests = (_destprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS - _srcs; \
++ _srcs = MPFR_PREC2LIMBS (_srcprec); \
++ _dests = MPFR_PREC2LIMBS (_destprec) - _srcs; \
+ MPN_COPY (_destp + _dests, srcp, _srcs); \
+ MPN_ZERO (_destp, _dests); \
+ inexact = 0; \
+@@ -1227,8 +1242,8 @@
+ mp_limb_t _rb, _sb, _ulp; \
+ \
+ /* Compute Position and shift */ \
+- _srcs = (_srcprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
+- _dests = (_destprec + GMP_NUMB_BITS-1)/GMP_NUMB_BITS; \
++ _srcs = MPFR_PREC2LIMBS (_srcprec); \
++ _dests = MPFR_PREC2LIMBS (_destprec); \
+ MPFR_UNSIGNED_MINUS_MODULO (_sh, _destprec); \
+ _sp = (srcp) + _srcs - _dests; \
+ \
+@@ -1372,7 +1387,7 @@
+ if (MPFR_LIKELY (MPFR_PREC (dest) == MPFR_PREC (src))) \
+ { \
+ MPN_COPY (MPFR_MANT (dest), MPFR_MANT (src), \
+- (MPFR_PREC (src) + GMP_NUMB_BITS-1)/GMP_NUMB_BITS); \
++ MPFR_LIMB_SIZE (src)); \
+ inexact = 0; \
+ } \
+ else \
+@@ -1682,7 +1697,7 @@
+ MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
+ if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
+ mpfr_abort_prec_max (); \
+- _size = (mpfr_prec_t) (_prec + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; \
++ _size = MPFR_PREC2LIMBS (_prec); \
+ if (MPFR_UNLIKELY (_size * (num) > MPFR_GROUP_STATIC_SIZE)) \
+ { \
+ (g).alloc = (num) * _size * sizeof (mp_limb_t); \
+@@ -1733,7 +1748,7 @@
+ MPFR_ASSERTD (_prec >= MPFR_PREC_MIN); \
+ if (MPFR_UNLIKELY (_prec > MPFR_PREC_MAX)) \
+ mpfr_abort_prec_max (); \
+- _size = (mpfr_prec_t) (_prec + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; \
++ _size = MPFR_PREC2LIMBS (_prec); \
+ (g).alloc = (num) * _size * sizeof (mp_limb_t); \
+ if (MPFR_LIKELY (_oalloc == 0)) \
+ (g).mant = (mp_limb_t *) (*__gmp_allocate_func) ((g).alloc); \
+@@ -1886,7 +1901,7 @@
+ MPFR_NORETURN_ATTR;
+
+ __MPFR_DECLSPEC void mpfr_rand_raw _MPFR_PROTO((mpfr_limb_ptr, gmp_randstate_t,
+- unsigned long));
++ mpfr_prec_t));
+
+ __MPFR_DECLSPEC mpz_t* mpfr_bernoulli_internal _MPFR_PROTO((mpz_t*,
+ unsigned long));
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2012-02-24 13:50:05.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-03-08 15:17:03.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p6"
++#define MPFR_VERSION_STRING "3.1.0-p7"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/mul.c mpfr-3.1.0-b/src/mul.c
+--- mpfr-3.1.0-a/src/mul.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/mul.c 2012-03-08 15:17:03.000000000 +0000
+@@ -93,15 +93,15 @@
+
+ ax = MPFR_GET_EXP (b) + MPFR_GET_EXP (c);
+
+- bq = MPFR_PREC(b);
+- cq = MPFR_PREC(c);
++ bq = MPFR_PREC (b);
++ cq = MPFR_PREC (c);
+
+- MPFR_ASSERTD(bq+cq > bq); /* PREC_MAX is /2 so no integer overflow */
++ MPFR_ASSERTN ((mpfr_uprec_t) bq + cq <= MPFR_PREC_MAX);
+
+- bn = (bq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of b */
+- cn = (cq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of c */
++ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
++ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
+- tn = (bq + cq + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
++ tn = MPFR_PREC2LIMBS (bq + cq);
+ /* <= k, thus no int overflow */
+ MPFR_ASSERTD(tn <= k);
+
+@@ -292,12 +292,12 @@
+ bq = MPFR_PREC (b);
+ cq = MPFR_PREC (c);
+
+- MPFR_ASSERTD (bq+cq > bq); /* PREC_MAX is /2 so no integer overflow */
++ MPFR_ASSERTN ((mpfr_uprec_t) bq + cq <= MPFR_PREC_MAX);
+
+- bn = (bq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of b */
+- cn = (cq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of c */
++ bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
++ cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
+ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
+- tn = (bq + cq + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
++ tn = MPFR_PREC2LIMBS (bq + cq);
+ MPFR_ASSERTD (tn <= k); /* tn <= k, thus no int overflow */
+
+ /* Check for no size_t overflow*/
+diff -Naurd mpfr-3.1.0-a/src/pow.c mpfr-3.1.0-b/src/pow.c
+--- mpfr-3.1.0-a/src/pow.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/pow.c 2012-03-08 15:17:03.000000000 +0000
+@@ -136,7 +136,7 @@
+ (b) all the 'z' bits are zero
+ */
+
+- prec = ((prec - 1) / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS - expo;
++ prec = MPFR_PREC2LIMBS (prec) * GMP_NUMB_BITS - expo;
+ /* number of z+0 bits */
+
+ yn = prec / GMP_NUMB_BITS;
+diff -Naurd mpfr-3.1.0-a/src/print_raw.c mpfr-3.1.0-b/src/print_raw.c
+--- mpfr-3.1.0-a/src/print_raw.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/print_raw.c 2012-03-08 15:17:03.000000000 +0000
+@@ -84,7 +84,7 @@
+ int i;
+ mpfr_prec_t count = 0;
+ char c;
+- mp_size_t n = (r - 1) / GMP_NUMB_BITS + 1;
++ mp_size_t n = MPFR_PREC2LIMBS (r);
+
+ printf("%s ", str);
+ for(n-- ; n>=0 ; n--)
+@@ -109,7 +109,7 @@
+ int i;
+ mpfr_prec_t count = 0;
+ char c;
+- mp_size_t n = (r - 1) / GMP_NUMB_BITS + 1;
++ mp_size_t n = MPFR_PREC2LIMBS (r);
+
+ for(n-- ; n>=0 ; n--)
+ {
+diff -Naurd mpfr-3.1.0-a/src/round_prec.c mpfr-3.1.0-b/src/round_prec.c
+--- mpfr-3.1.0-a/src/round_prec.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/round_prec.c 2012-03-08 15:17:03.000000000 +0000
+@@ -55,12 +55,12 @@
+
+ MPFR_ASSERTN(prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX);
+
+- nw = 1 + (prec - 1) / GMP_NUMB_BITS; /* needed allocated limbs */
++ nw = MPFR_PREC2LIMBS (prec); /* needed allocated limbs */
+
+ /* check if x has enough allocated space for the significand */
+ /* Get the number of limbs from the precision.
+ (Compatible with all allocation methods) */
+- ow = (MPFR_PREC (x) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
++ ow = MPFR_LIMB_SIZE (x);
+ if (nw > ow)
+ {
+ /* FIXME: Variable can't be created using custom allocation,
+diff -Naurd mpfr-3.1.0-a/src/round_raw_generic.c mpfr-3.1.0-b/src/round_raw_generic.c
+--- mpfr-3.1.0-a/src/round_raw_generic.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/round_raw_generic.c 2012-03-08 15:17:03.000000000 +0000
+@@ -80,7 +80,7 @@
+ (xprec <= yprec || MPFR_IS_LIKE_RNDZ (rnd_mode, neg)))
+ return 0;
+
+- xsize = (xprec-1)/GMP_NUMB_BITS + 1;
++ xsize = MPFR_PREC2LIMBS (xprec);
+ nw = yprec / GMP_NUMB_BITS;
+ rw = yprec & (GMP_NUMB_BITS - 1);
+
+diff -Naurd mpfr-3.1.0-a/src/set.c mpfr-3.1.0-b/src/set.c
+--- mpfr-3.1.0-a/src/set.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/set.c 2012-03-08 15:17:03.000000000 +0000
+@@ -48,8 +48,7 @@
+ /* Same precision and b is not singular:
+ * just copy the mantissa, and set the exponent and the sign
+ * The result is exact. */
+- MPN_COPY (MPFR_MANT (a), MPFR_MANT (b),
+- (MPFR_PREC (b) + GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
++ MPN_COPY (MPFR_MANT (a), MPFR_MANT (b), MPFR_LIMB_SIZE (b));
+ MPFR_RET (0);
+ }
+ else
+diff -Naurd mpfr-3.1.0-a/src/set_f.c mpfr-3.1.0-b/src/set_f.c
+--- mpfr-3.1.0-a/src/set_f.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/set_f.c 2012-03-08 15:17:03.000000000 +0000
+@@ -43,7 +43,7 @@
+ if (SIZ(x) * MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0)
+ MPFR_CHANGE_SIGN (y);
+
+- sy = 1 + (MPFR_PREC(y) - 1) / GMP_NUMB_BITS;
++ sy = MPFR_LIMB_SIZE (y);
+ my = MPFR_MANT(y);
+ mx = PTR(x);
+
+diff -Naurd mpfr-3.1.0-a/src/set_prec.c mpfr-3.1.0-b/src/set_prec.c
+--- mpfr-3.1.0-a/src/set_prec.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/set_prec.c 2012-03-08 15:17:03.000000000 +0000
+@@ -32,7 +32,7 @@
+ MPFR_ASSERTN (p >= MPFR_PREC_MIN && p <= MPFR_PREC_MAX);
+
+ /* Calculate the new number of limbs */
+- xsize = (p - 1) / GMP_NUMB_BITS + 1;
++ xsize = MPFR_PREC2LIMBS (p);
+
+ /* Realloc only if the new size is greater than the old */
+ xoldsize = MPFR_GET_ALLOC_SIZE (x);
+diff -Naurd mpfr-3.1.0-a/src/setmax.c mpfr-3.1.0-b/src/setmax.c
+--- mpfr-3.1.0-a/src/setmax.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/setmax.c 2012-03-08 15:17:03.000000000 +0000
+@@ -32,7 +32,7 @@
+ mp_limb_t *xp;
+
+ MPFR_SET_EXP (x, e);
+- xn = 1 + (MPFR_PREC(x) - 1) / GMP_NUMB_BITS;
++ xn = MPFR_LIMB_SIZE (x);
+ sh = (mpfr_prec_t) xn * GMP_NUMB_BITS - MPFR_PREC(x);
+ xp = MPFR_MANT(x);
+ xp[0] = MP_LIMB_T_MAX << sh;
+diff -Naurd mpfr-3.1.0-a/src/sqr.c mpfr-3.1.0-b/src/sqr.c
+--- mpfr-3.1.0-a/src/sqr.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/sqr.c 2012-03-08 15:17:03.000000000 +0000
+@@ -56,11 +56,11 @@
+ ax = 2 * MPFR_GET_EXP (b);
+ bq = MPFR_PREC(b);
+
+- MPFR_ASSERTD (2 * bq > bq); /* PREC_MAX is /2 so no integer overflow */
++ MPFR_ASSERTN (2 * (mpfr_uprec_t) bq <= MPFR_PREC_MAX);
+
+- bn = MPFR_LIMB_SIZE(b); /* number of limbs of b */
+- tn = 1 + (2 * bq - 1) / GMP_NUMB_BITS; /* number of limbs of square,
+- 2*bn or 2*bn-1 */
++ bn = MPFR_LIMB_SIZE (b); /* number of limbs of b */
++ tn = MPFR_PREC2LIMBS (2 * bq); /* number of limbs of square,
++ 2*bn or 2*bn-1 */
+
+ if (MPFR_UNLIKELY(bn > MPFR_SQR_THRESHOLD))
+ return mpfr_mul (a, b, b, rnd_mode);
+diff -Naurd mpfr-3.1.0-a/src/stack_interface.c mpfr-3.1.0-b/src/stack_interface.c
+--- mpfr-3.1.0-a/src/stack_interface.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/stack_interface.c 2012-03-08 15:17:03.000000000 +0000
+@@ -26,7 +26,7 @@
+ size_t
+ mpfr_custom_get_size (mpfr_prec_t prec)
+ {
+- return (prec + GMP_NUMB_BITS -1) / GMP_NUMB_BITS * BYTES_PER_MP_LIMB;
++ return MPFR_PREC2LIMBS (prec) * BYTES_PER_MP_LIMB;
+ }
+
+ #undef mpfr_custom_init
+diff -Naurd mpfr-3.1.0-a/src/strtofr.c mpfr-3.1.0-b/src/strtofr.c
+--- mpfr-3.1.0-a/src/strtofr.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/strtofr.c 2012-03-08 15:17:03.000000000 +0000
+@@ -467,7 +467,7 @@
+ /* Set y to the value of the ~prec most significant bits of pstr->mant
+ (as long as we guarantee correct rounding, we don't need to get
+ exactly prec bits). */
+- ysize = (prec - 1) / GMP_NUMB_BITS + 1;
++ ysize = MPFR_PREC2LIMBS (prec);
+ /* prec bits corresponds to ysize limbs */
+ ysize_bits = ysize * GMP_NUMB_BITS;
+ /* and to ysize_bits >= prec > MPFR_PREC (x) bits */
+diff -Naurd mpfr-3.1.0-a/src/sub1sp.c mpfr-3.1.0-b/src/sub1sp.c
+--- mpfr-3.1.0-a/src/sub1sp.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/sub1sp.c 2012-03-08 15:17:03.000000000 +0000
+@@ -155,8 +155,8 @@
+ MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
+
+ /* Read prec and num of limbs */
+- p = MPFR_PREC(b);
+- n = (p-1)/GMP_NUMB_BITS+1;
++ p = MPFR_PREC (b);
++ n = MPFR_PREC2LIMBS (p);
+
+ /* Fast cmp of |b| and |c|*/
+ bx = MPFR_GET_EXP (b);
+diff -Naurd mpfr-3.1.0-a/src/urandomb.c mpfr-3.1.0-b/src/urandomb.c
+--- mpfr-3.1.0-a/src/urandomb.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/urandomb.c 2012-03-08 15:17:03.000000000 +0000
+@@ -31,13 +31,20 @@
+ a sufficient number of limbs */
+ void
+ mpfr_rand_raw (mpfr_limb_ptr mp, gmp_randstate_t rstate,
+- unsigned long int nbits)
++ mpfr_prec_t nbits)
+ {
+ mpz_t z;
+
++ MPFR_ASSERTN (nbits >= 1);
+ /* To be sure to avoid the potential allocation of mpz_urandomb */
+- ALLOC(z) = SIZ(z) = ((nbits - 1) / GMP_NUMB_BITS) + 1;
++ ALLOC(z) = SIZ(z) = MPFR_PREC2LIMBS (nbits);
+ PTR(z) = mp;
++#if __MPFR_GMP(5,0,0)
++ /* Check for integer overflow (unless mp_bitcnt_t is signed,
++ but according to the GMP manual, this shouldn't happen).
++ Note: mp_bitcnt_t has been introduced in GMP 5.0.0. */
++ MPFR_ASSERTN ((mp_bitcnt_t) -1 < 0 || nbits <= (mp_bitcnt_t) -1);
++#endif
+ mpz_urandomb (z, rstate, nbits);
+ }
+
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2012-02-24 13:50:05.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-03-08 15:17:03.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p6";
++ return "3.1.0-p7";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/tinits.c mpfr-3.1.0-b/tests/tinits.c
+--- mpfr-3.1.0-a/tests/tinits.c 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/tinits.c 2012-03-08 15:17:03.000000000 +0000
+@@ -1,4 +1,4 @@
+-/* Test file for mpfr_inits, mpfr_inits2 and mpfr_clears.
++/* Test file for mpfr_init2, mpfr_inits, mpfr_inits2 and mpfr_clears.
+
+ Copyright 2003, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Contributed by the Arenaire and Caramel projects, INRIA.
+@@ -20,18 +20,43 @@
+ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
++#include <stdlib.h>
++
+ #include "mpfr-test.h"
+
+ int
+ main (void)
+ {
+ mpfr_t a, b, c;
++ long large_prec;
+
+ tests_start_mpfr ();
++
+ mpfr_inits (a, b, c, (mpfr_ptr) 0);
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
+ mpfr_inits2 (200, a, b, c, (mpfr_ptr) 0);
+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
++
++ /* test for precision 2^31-1, see
++ https://gforge.inria.fr/tracker/index.php?func=detail&aid=13918 */
++ large_prec = 2147483647;
++ if (getenv ("MPFR_CHECK_LARGEMEM") != NULL)
++ {
++ /* We assume that the precision won't be increased internally. */
++ if (large_prec > MPFR_PREC_MAX)
++ large_prec = MPFR_PREC_MAX;
++ mpfr_inits2 (large_prec, a, b, (mpfr_ptr) 0);
++ mpfr_set_ui (a, 17, MPFR_RNDN);
++ mpfr_set (b, a, MPFR_RNDN);
++ if (mpfr_get_ui (a, MPFR_RNDN) != 17)
++ {
++ printf ("Error in mpfr_init2 with precision 2^31-1\n");
++ exit (1);
++ }
++ mpfr_clears (a, b, (mpfr_ptr) 0);
++ }
++
+ tests_end_mpfr ();
++
+ return 0;
+ }
diff --git a/patches/mpfr/3.1.0/180-__gmp_const.patch b/patches/mpfr/3.1.0/180-__gmp_const.patch
new file mode 100644
index 0000000..94444b6
--- /dev/null
+++ b/patches/mpfr/3.1.0/180-__gmp_const.patch
@@ -0,0 +1,52 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-03-12 11:59:47.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-03-12 11:59:47.000000000 +0000
+@@ -0,0 +1 @@
++__gmp_const
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2012-03-08 15:17:03.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-03-12 11:59:47.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p7
++3.1.0-p8
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2012-03-08 15:17:03.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-03-12 11:59:47.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p7"
++#define MPFR_VERSION_STRING "3.1.0-p8"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -39,6 +39,18 @@
+ # include <gmp.h>
+ #endif
+
++/* GMP's internal __gmp_const macro has been removed on 2012-03-04:
++ http://gmplib.org:8000/gmp/rev/d287cfaf6732
++ const is standard and now assumed to be available. If the __gmp_const
++ definition is no longer present in GMP, this probably means that GMP
++ assumes that const is available; thus let's define it to const.
++ Note: this is a temporary fix that can be backported to previous MPFR
++ versions. In the future, __gmp_const should be replaced by const like
++ in GMP. */
++#ifndef __gmp_const
++# define __gmp_const const
++#endif
++
+ /* Avoid some problems with macro expansion if the user defines macros
+ with the same name as keywords. By convention, identifiers and macro
+ names starting with mpfr_ are reserved by MPFR. */
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2012-03-08 15:17:03.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-03-12 11:59:47.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p7";
++ return "3.1.0-p8";
+ }
diff --git a/patches/mpfr/3.1.0/190-gamma-underflow.patch b/patches/mpfr/3.1.0/190-gamma-underflow.patch
new file mode 100644
index 0000000..3de1d19
--- /dev/null
+++ b/patches/mpfr/3.1.0/190-gamma-underflow.patch
@@ -0,0 +1,93 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-04-27 01:13:15.000000000 +0000
+@@ -0,0 +1 @@
++gamma-underflow
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2012-03-12 11:59:47.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-04-27 01:13:15.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p8
++3.1.0-p9
+diff -Naurd mpfr-3.1.0-a/src/gamma.c mpfr-3.1.0-b/src/gamma.c
+--- mpfr-3.1.0-a/src/gamma.c 2011-10-03 08:17:09.000000000 +0000
++++ mpfr-3.1.0-b/src/gamma.c 2012-04-27 01:13:15.000000000 +0000
+@@ -296,7 +296,7 @@
+ /* we want an upper bound for x * [log(2-x)-1].
+ since x < 0, we need a lower bound on log(2-x) */
+ mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
+- mpfr_log2 (xp, xp, MPFR_RNDD);
++ mpfr_log (xp, xp, MPFR_RNDD);
+ mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
+ mpfr_mul (xp, xp, x, MPFR_RNDU);
+
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2012-03-12 11:59:47.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-04-27 01:13:15.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p8"
++#define MPFR_VERSION_STRING "3.1.0-p9"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2012-03-12 11:59:47.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-04-27 01:13:15.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p8";
++ return "3.1.0-p9";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/tgamma.c mpfr-3.1.0-b/tests/tgamma.c
+--- mpfr-3.1.0-a/tests/tgamma.c 2011-10-03 08:17:14.000000000 +0000
++++ mpfr-3.1.0-b/tests/tgamma.c 2012-04-27 01:13:15.000000000 +0000
+@@ -478,6 +478,36 @@
+ mpfr_clear (x);
+ }
+
++/* bug found by Giridhar Tammana */
++static void
++test20120426 (void)
++{
++ mpfr_t xa, xb;
++ int i;
++ mpfr_exp_t emin;
++
++ mpfr_init2 (xa, 53);
++ mpfr_init2 (xb, 53);
++ mpfr_set_d (xb, -168.5, MPFR_RNDN);
++ emin = mpfr_get_emin ();
++ mpfr_set_emin (-1073);
++ i = mpfr_gamma (xa, xb, MPFR_RNDN);
++ i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */
++ mpfr_set_str (xb, "-9.5737343987585366746184749943e-304", 10, MPFR_RNDN);
++ if (!((i > 0) && (mpfr_cmp (xa, xb) == 0)))
++ {
++ printf ("Error in test20120426, i=%d\n", i);
++ printf ("expected ");
++ mpfr_print_binary (xb); putchar ('\n');
++ printf ("got ");
++ mpfr_print_binary (xa); putchar ('\n');
++ exit (1);
++ }
++ mpfr_set_emin (emin);
++ mpfr_clear (xa);
++ mpfr_clear (xb);
++}
++
+ static void
+ exprange (void)
+ {
+@@ -821,6 +851,7 @@
+ gamma_integer ();
+ test20071231 ();
+ test20100709 ();
++ test20120426 ();
+
+ data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
+
diff --git a/patches/mpfr/3.1.0/200-gamma-overunderflow.patch b/patches/mpfr/3.1.0/200-gamma-overunderflow.patch
new file mode 100644
index 0000000..e6d6051
--- /dev/null
+++ b/patches/mpfr/3.1.0/200-gamma-overunderflow.patch
@@ -0,0 +1,487 @@
+diff -Naurd mpfr-3.1.0-a/PATCHES mpfr-3.1.0-b/PATCHES
+--- mpfr-3.1.0-a/PATCHES 2012-05-07 18:52:45.000000000 +0000
++++ mpfr-3.1.0-b/PATCHES 2012-05-07 18:52:45.000000000 +0000
+@@ -0,0 +1 @@
++gamma-overunderflow
+diff -Naurd mpfr-3.1.0-a/VERSION mpfr-3.1.0-b/VERSION
+--- mpfr-3.1.0-a/VERSION 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/VERSION 2012-05-07 18:52:45.000000000 +0000
+@@ -1 +1 @@
+-3.1.0-p9
++3.1.0-p10
+diff -Naurd mpfr-3.1.0-a/src/gamma.c mpfr-3.1.0-b/src/gamma.c
+--- mpfr-3.1.0-a/src/gamma.c 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/src/gamma.c 2012-05-07 18:52:45.000000000 +0000
+@@ -100,7 +100,8 @@
+ mpfr_t xp, GammaTrial, tmp, tmp2;
+ mpz_t fact;
+ mpfr_prec_t realprec;
+- int compared, inex, is_integer;
++ int compared, is_integer;
++ int inex = 0; /* 0 means: result gamma not set yet */
+ MPFR_GROUP_DECL (group);
+ MPFR_SAVE_EXPO_DECL (expo);
+ MPFR_ZIV_DECL (loop);
+@@ -377,6 +378,15 @@
+ mpfr_mul (GammaTrial, tmp2, xp, MPFR_RNDN); /* Pi*(2-x), error (1+u)^2 */
+ err_g = MPFR_GET_EXP(GammaTrial);
+ mpfr_sin (GammaTrial, GammaTrial, MPFR_RNDN); /* sin(Pi*(2-x)) */
++ /* If tmp is +Inf, we compute exp(lngamma(x)). */
++ if (mpfr_inf_p (tmp))
++ {
++ inex = mpfr_explgamma (gamma, x, &expo, tmp, tmp2, rnd_mode);
++ if (inex)
++ goto end;
++ else
++ goto ziv_next;
++ }
+ err_g = err_g + 1 - MPFR_GET_EXP(GammaTrial);
+ /* let g0 the true value of Pi*(2-x), g the computed value.
+ We have g = g0 + h with |h| <= |(1+u^2)-1|*g.
+@@ -411,11 +421,16 @@
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (GammaTrial, realprec - err_g,
+ MPFR_PREC(gamma), rnd_mode)))
+ break;
++
++ ziv_next:
+ MPFR_ZIV_NEXT (loop, realprec);
+ }
++
++ end:
+ MPFR_ZIV_FREE (loop);
+
+- inex = mpfr_set (gamma, GammaTrial, rnd_mode);
++ if (inex == 0)
++ inex = mpfr_set (gamma, GammaTrial, rnd_mode);
+ MPFR_GROUP_CLEAR (group);
+ mpz_clear (fact);
+
+diff -Naurd mpfr-3.1.0-a/src/lngamma.c mpfr-3.1.0-b/src/lngamma.c
+--- mpfr-3.1.0-a/src/lngamma.c 2012-03-08 15:17:03.000000000 +0000
++++ mpfr-3.1.0-b/src/lngamma.c 2012-05-07 18:52:45.000000000 +0000
+@@ -49,9 +49,72 @@
+ mpfr_set_ui_2exp (s, 9, -1, MPFR_RNDN); /* 4.5 */
+ }
+
+-#ifndef IS_GAMMA
++#ifdef IS_GAMMA
++
++/* This function is called in case of intermediate overflow/underflow.
++ The s1 and s2 arguments are temporary MPFR numbers, having the
++ working precision. If the result could be determined, then the
++ flags are updated via pexpo, y is set to the result, and the
++ (non-zero) ternary value is returned. Otherwise 0 is returned
++ in order to perform the next Ziv iteration. */
+ static int
+-unit_bit (mpfr_srcptr (x))
++mpfr_explgamma (mpfr_ptr y, mpfr_srcptr x, mpfr_save_expo_t *pexpo,
++ mpfr_ptr s1, mpfr_ptr s2, mpfr_rnd_t rnd)
++{
++ mpfr_t t1, t2;
++ int inex1, inex2, sign;
++ MPFR_BLOCK_DECL (flags1);
++ MPFR_BLOCK_DECL (flags2);
++ MPFR_GROUP_DECL (group);
++
++ MPFR_BLOCK (flags1, inex1 = mpfr_lgamma (s1, &sign, x, MPFR_RNDD));
++ MPFR_ASSERTN (inex1 != 0);
++ /* s1 = RNDD(lngamma(x)), inexact */
++ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags1)))
++ {
++ if (MPFR_SIGN (s1) > 0)
++ {
++ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, MPFR_FLAGS_OVERFLOW);
++ return mpfr_overflow (y, rnd, sign);
++ }
++ else
++ {
++ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, MPFR_FLAGS_UNDERFLOW);
++ return mpfr_underflow (y, rnd == MPFR_RNDN ? MPFR_RNDZ : rnd, sign);
++ }
++ }
++
++ mpfr_set (s2, s1, MPFR_RNDN); /* exact */
++ mpfr_nextabove (s2); /* v = RNDU(lngamma(z0)) */
++
++ if (sign < 0)
++ rnd = MPFR_INVERT_RND (rnd); /* since the result with be negated */
++ MPFR_GROUP_INIT_2 (group, MPFR_PREC (y), t1, t2);
++ MPFR_BLOCK (flags1, inex1 = mpfr_exp (t1, s1, rnd));
++ MPFR_BLOCK (flags2, inex2 = mpfr_exp (t2, s2, rnd));
++ /* t1 is the rounding with mode 'rnd' of a lower bound on |Gamma(x)|,
++ t2 is the rounding with mode 'rnd' of an upper bound, thus if both
++ are equal, so is the wanted result. If t1 and t2 differ or the flags
++ differ, at some point of Ziv's loop they should agree. */
++ if (mpfr_equal_p (t1, t2) && flags1 == flags2)
++ {
++ MPFR_ASSERTN ((inex1 > 0 && inex2 > 0) || (inex1 < 0 && inex2 < 0));
++ mpfr_set4 (y, t1, MPFR_RNDN, sign); /* exact */
++ if (sign < 0)
++ inex1 = - inex1;
++ MPFR_SAVE_EXPO_UPDATE_FLAGS (*pexpo, flags1);
++ }
++ else
++ inex1 = 0; /* couldn't determine the result */
++ MPFR_GROUP_CLEAR (group);
++
++ return inex1;
++}
++
++#else
++
++static int
++unit_bit (mpfr_srcptr x)
+ {
+ mpfr_exp_t expo;
+ mpfr_prec_t prec;
+@@ -75,6 +138,7 @@
+
+ return (x0 >> (prec % GMP_NUMB_BITS)) & 1;
+ }
++
+ #endif
+
+ /* lngamma(x) = log(gamma(x)).
+@@ -99,12 +163,14 @@
+ mpfr_t s, t, u, v, z;
+ unsigned long m, k, maxm;
+ mpz_t *INITIALIZED(B); /* variable B declared as initialized */
+- int inexact, compared;
++ int compared;
++ int inexact = 0; /* 0 means: result y not set yet */
+ mpfr_exp_t err_s, err_t;
+ unsigned long Bm = 0; /* number of allocated B[] */
+ unsigned long oldBm;
+ double d;
+ MPFR_SAVE_EXPO_DECL (expo);
++ MPFR_ZIV_DECL (loop);
+
+ compared = mpfr_cmp_ui (z0, 1);
+
+@@ -122,7 +188,7 @@
+ if (MPFR_EXP(z0) <= - (mpfr_exp_t) MPFR_PREC(y))
+ {
+ mpfr_t l, h, g;
+- int ok, inex2;
++ int ok, inex1, inex2;
+ mpfr_prec_t prec = MPFR_PREC(y) + 14;
+ MPFR_ZIV_DECL (loop);
+
+@@ -157,14 +223,14 @@
+ mpfr_sub (h, h, g, MPFR_RNDD);
+ mpfr_mul (g, z0, z0, MPFR_RNDU);
+ mpfr_add (h, h, g, MPFR_RNDU);
+- inexact = mpfr_prec_round (l, MPFR_PREC(y), rnd);
++ inex1 = mpfr_prec_round (l, MPFR_PREC(y), rnd);
+ inex2 = mpfr_prec_round (h, MPFR_PREC(y), rnd);
+ /* Caution: we not only need l = h, but both inexact flags should
+ agree. Indeed, one of the inexact flags might be zero. In that
+ case if we assume lngamma(z0) cannot be exact, the other flag
+ should be correct. We are conservative here and request that both
+ inexact flags agree. */
+- ok = SAME_SIGN (inexact, inex2) && mpfr_cmp (l, h) == 0;
++ ok = SAME_SIGN (inex1, inex2) && mpfr_cmp (l, h) == 0;
+ if (ok)
+ mpfr_set (y, h, rnd); /* exact */
+ mpfr_clear (l);
+@@ -172,8 +238,9 @@
+ mpfr_clear (g);
+ if (ok)
+ {
++ MPFR_ZIV_FREE (loop);
+ MPFR_SAVE_EXPO_FREE (expo);
+- return mpfr_check_range (y, inexact, rnd);
++ return mpfr_check_range (y, inex1, rnd);
+ }
+ /* since we have log|gamma(x)| = - log|x| - gamma*x + O(x^2),
+ if x ~ 2^(-n), then we have a n-bit approximation, thus
+@@ -205,9 +272,10 @@
+ thus lngamma(x) = log(Pi*(x-1)/sin(Pi*(2-x))) - lngamma(2-x) */
+
+ w = precy + MPFR_INT_CEIL_LOG2 (precy);
++ w += MPFR_INT_CEIL_LOG2 (w) + 14;
++ MPFR_ZIV_INIT (loop, w);
+ while (1)
+ {
+- w += MPFR_INT_CEIL_LOG2 (w) + 14;
+ MPFR_ASSERTD(w >= 3);
+ mpfr_set_prec (s, w);
+ mpfr_set_prec (t, w);
+@@ -288,7 +356,9 @@
+ + (rnd == MPFR_RNDN)))
+ goto end;
+ }
++ MPFR_ZIV_NEXT (loop, w);
+ }
++ MPFR_ZIV_FREE (loop);
+ }
+
+ /* now z0 > 1 */
+@@ -298,10 +368,10 @@
+ /* since k is O(w), the value of log(z0*...*(z0+k-1)) is about w*log(w),
+ so there is a cancellation of ~log(w) in the argument reconstruction */
+ w = precy + MPFR_INT_CEIL_LOG2 (precy);
+-
+- do
++ w += MPFR_INT_CEIL_LOG2 (w) + 13;
++ MPFR_ZIV_INIT (loop, w);
++ while (1)
+ {
+- w += MPFR_INT_CEIL_LOG2 (w) + 13;
+ MPFR_ASSERTD (w >= 3);
+
+ /* argument reduction: we compute gamma(z0 + k), where the series
+@@ -441,6 +511,15 @@
+ #ifdef IS_GAMMA
+ err_s = MPFR_GET_EXP(s);
+ mpfr_exp (s, s, MPFR_RNDN);
++ /* If s is +Inf, we compute exp(lngamma(z0)). */
++ if (mpfr_inf_p (s))
++ {
++ inexact = mpfr_explgamma (y, z0, &expo, s, t, rnd);
++ if (inexact)
++ goto end0;
++ else
++ goto ziv_next;
++ }
+ /* before the exponential, we have s = s0 + h where
+ |h| <= (2m+48)*ulp(s), thus exp(s0) = exp(s) * exp(-h).
+ For |h| <= 1/4, we have |exp(h)-1| <= 1.2*|h| thus
+@@ -480,16 +559,26 @@
+ err_s = (err_t == err_s) ? 1 + err_s : ((err_t > err_s) ? err_t : err_s);
+ err_s += 1 - MPFR_GET_EXP(s);
+ #endif
++ if (MPFR_LIKELY (MPFR_CAN_ROUND (s, w - err_s, precy, rnd)))
++ break;
++#ifdef IS_GAMMA
++ ziv_next:
++#endif
++ MPFR_ZIV_NEXT (loop, w);
+ }
+- while (MPFR_UNLIKELY (!MPFR_CAN_ROUND (s, w - err_s, precy, rnd)));
+
++#ifdef IS_GAMMA
++ end0:
++#endif
+ oldBm = Bm;
+ while (Bm--)
+ mpz_clear (B[Bm]);
+ (*__gmp_free_func) (B, oldBm * sizeof (mpz_t));
+
+ end:
+- inexact = mpfr_set (y, s, rnd);
++ if (inexact == 0)
++ inexact = mpfr_set (y, s, rnd);
++ MPFR_ZIV_FREE (loop);
+
+ mpfr_clear (s);
+ mpfr_clear (t);
+diff -Naurd mpfr-3.1.0-a/src/mpfr.h mpfr-3.1.0-b/src/mpfr.h
+--- mpfr-3.1.0-a/src/mpfr.h 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/src/mpfr.h 2012-05-07 18:52:45.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.1.0-p9"
++#define MPFR_VERSION_STRING "3.1.0-p10"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.0-a/src/version.c mpfr-3.1.0-b/src/version.c
+--- mpfr-3.1.0-a/src/version.c 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/src/version.c 2012-05-07 18:52:45.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.0-p9";
++ return "3.1.0-p10";
+ }
+diff -Naurd mpfr-3.1.0-a/tests/tgamma.c mpfr-3.1.0-b/tests/tgamma.c
+--- mpfr-3.1.0-a/tests/tgamma.c 2012-04-27 01:13:15.000000000 +0000
++++ mpfr-3.1.0-b/tests/tgamma.c 2012-05-07 18:52:45.000000000 +0000
+@@ -838,6 +838,175 @@
+ exit (1);
+ }
+
++/* Test mpfr_gamma in precision p1 by comparing it with exp(lgamma(x))
++ computing with a working precision p2. Assume that x is not an
++ integer <= 2. */
++static void
++exp_lgamma (mpfr_t x, mpfr_prec_t p1, mpfr_prec_t p2)
++{
++ mpfr_t yd, yu, zd, zu;
++ int inexd, inexu, sign;
++ int underflow = -1, overflow = -1; /* -1: we don't know */
++ int got_underflow, got_overflow;
++
++ if (mpfr_integer_p (x) && mpfr_cmp_si (x, 2) <= 0)
++ {
++ printf ("Warning! x is an integer <= 2 in exp_lgamma: ");
++ mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
++ return;
++ }
++ mpfr_inits2 (p2, yd, yu, (mpfr_ptr) 0);
++ inexd = mpfr_lgamma (yd, &sign, x, MPFR_RNDD);
++ mpfr_set (yu, yd, MPFR_RNDN); /* exact */
++ if (inexd)
++ mpfr_nextabove (yu);
++ mpfr_clear_flags ();
++ mpfr_exp (yd, yd, MPFR_RNDD);
++ if (! mpfr_underflow_p ())
++ underflow = 0;
++ if (mpfr_overflow_p ())
++ overflow = 1;
++ mpfr_clear_flags ();
++ mpfr_exp (yu, yu, MPFR_RNDU);
++ if (mpfr_underflow_p ())
++ underflow = 1;
++ if (! mpfr_overflow_p ())
++ overflow = 0;
++ if (sign < 0)
++ {
++ mpfr_neg (yd, yd, MPFR_RNDN); /* exact */
++ mpfr_neg (yu, yu, MPFR_RNDN); /* exact */
++ mpfr_swap (yd, yu);
++ }
++ /* yd < Gamma(x) < yu (strict inequalities since x != 1 and x != 2) */
++ mpfr_inits2 (p1, zd, zu, (mpfr_ptr) 0);
++ mpfr_clear_flags ();
++ inexd = mpfr_gamma (zd, x, MPFR_RNDD); /* zd <= Gamma(x) < yu */
++ got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
++ got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
++ if (! mpfr_less_p (zd, yu) || inexd > 0 ||
++ got_underflow != underflow ||
++ got_overflow != overflow)
++ {
++ printf ("Error in exp_lgamma on x = ");
++ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
++ printf ("yu = ");
++ mpfr_dump (yu);
++ printf ("zd = ");
++ mpfr_dump (zd);
++ printf ("got inexd = %d, expected <= 0\n", inexd);
++ printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
++ printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
++ exit (1);
++ }
++ mpfr_clear_flags ();
++ inexu = mpfr_gamma (zu, x, MPFR_RNDU); /* zu >= Gamma(x) > yd */
++ got_underflow = underflow == -1 ? -1 : !! mpfr_underflow_p ();
++ got_overflow = overflow == -1 ? -1 : !! mpfr_overflow_p ();
++ if (! mpfr_greater_p (zu, yd) || inexu < 0 ||
++ got_underflow != underflow ||
++ got_overflow != overflow)
++ {
++ printf ("Error in exp_lgamma on x = ");
++ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
++ printf ("yd = ");
++ mpfr_dump (yd);
++ printf ("zu = ");
++ mpfr_dump (zu);
++ printf ("got inexu = %d, expected >= 0\n", inexu);
++ printf ("got underflow = %d, expected %d\n", got_underflow, underflow);
++ printf ("got overflow = %d, expected %d\n", got_overflow, overflow);
++ exit (1);
++ }
++ if (mpfr_equal_p (zd, zu))
++ {
++ if (inexd != 0 || inexu != 0)
++ {
++ printf ("Error in exp_lgamma on x = ");
++ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
++ printf ("zd = zu, thus exact, but inexd = %d and inexu = %d\n",
++ inexd, inexu);
++ exit (1);
++ }
++ MPFR_ASSERTN (got_underflow == 0);
++ MPFR_ASSERTN (got_overflow == 0);
++ }
++ else if (inexd == 0 || inexu == 0)
++ {
++ printf ("Error in exp_lgamma on x = ");
++ mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
++ printf ("zd != zu, thus inexact, but inexd = %d and inexu = %d\n",
++ inexd, inexu);
++ exit (1);
++ }
++ mpfr_clears (yd, yu, zd, zu, (mpfr_ptr) 0);
++}
++
++static void
++exp_lgamma_tests (void)
++{
++ mpfr_t x;
++ mpfr_exp_t emin, emax;
++ int i;
++
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++ set_emin (MPFR_EMIN_MIN);
++ set_emax (MPFR_EMAX_MAX);
++
++ mpfr_init2 (x, 96);
++ for (i = 3; i <= 8; i++)
++ {
++ mpfr_set_ui (x, i, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ mpfr_nextbelow (x);
++ exp_lgamma (x, 53, 64);
++ mpfr_nextabove (x);
++ mpfr_nextabove (x);
++ exp_lgamma (x, 53, 64);
++ }
++ mpfr_set_str (x, "1.7", 10, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ mpfr_set_str (x, "-90.6308260837372266e+15", 10, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ /* The following test gives a large positive result < +Inf */
++ mpfr_set_str (x, "1.2b13fc45a92dea1@14", 16, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ /* Idem for a large negative result > -Inf */
++ mpfr_set_str (x, "-1.2b13fc45a92de81@14", 16, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ /* The following two tests trigger an endless loop in r8186
++ on 64-bit machines (64-bit exponent). The second one (due
++ to undetected overflow) is a direct consequence of the
++ first one, due to the call of Gamma(2-x) if x < 1. */
++ mpfr_set_str (x, "1.2b13fc45a92dec8@14", 16, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ mpfr_set_str (x, "-1.2b13fc45a92dea8@14", 16, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ /* Similar tests (overflow threshold) for 32-bit machines. */
++ mpfr_set_str (x, "2ab68d8.657542f855111c61", 16, MPFR_RNDN);
++ exp_lgamma (x, 12, 64);
++ mpfr_set_str (x, "-2ab68d6.657542f855111c61", 16, MPFR_RNDN);
++ exp_lgamma (x, 12, 64);
++ /* The following test is an overflow on 32-bit and 64-bit machines.
++ Revision r8189 fails on 64-bit machines as the flag is unset. */
++ mpfr_set_str (x, "1.2b13fc45a92ded8@14", 16, MPFR_RNDN);
++ exp_lgamma (x, 53, 64);
++ /* On the following tests, with r8196, one gets an underflow on
++ 32-bit machines, while a normal result is expected (see FIXME
++ in gamma.c:382). */
++ mpfr_set_str (x, "-2ab68d6.657542f855111c6104", 16, MPFR_RNDN);
++ exp_lgamma (x, 12, 64); /* failure on 32-bit machines */
++ mpfr_set_str (x, "-12b13fc45a92deb.1c6c5bc964", 16, MPFR_RNDN);
++ exp_lgamma (x, 12, 64); /* failure on 64-bit machines */
++ mpfr_clear (x);
++
++ set_emin (emin);
++ set_emax (emax);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -852,6 +1021,7 @@
+ test20071231 ();
+ test20100709 ();
+ test20120426 ();
++ exp_lgamma_tests ();
+
+ data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
+
diff --git a/patches/mpfr/3.1.1/110-get_decimal64.patch b/patches/mpfr/3.1.1/110-get_decimal64.patch
new file mode 100644
index 0000000..d73a3d7
--- /dev/null
+++ b/patches/mpfr/3.1.1/110-get_decimal64.patch
@@ -0,0 +1,235 @@
+diff -Naurd mpfr-3.1.1-a/PATCHES mpfr-3.1.1-b/PATCHES
+--- mpfr-3.1.1-a/PATCHES 2012-08-30 09:28:51.000000000 +0000
++++ mpfr-3.1.1-b/PATCHES 2012-08-30 09:28:51.000000000 +0000
+@@ -0,0 +1 @@
++get_decimal64
+diff -Naurd mpfr-3.1.1-a/VERSION mpfr-3.1.1-b/VERSION
+--- mpfr-3.1.1-a/VERSION 2012-07-03 15:01:13.000000000 +0000
++++ mpfr-3.1.1-b/VERSION 2012-08-30 09:28:51.000000000 +0000
+@@ -1 +1 @@
+-3.1.1
++3.1.1-p1
+diff -Naurd mpfr-3.1.1-a/src/get_d64.c mpfr-3.1.1-b/src/get_d64.c
+--- mpfr-3.1.1-a/src/get_d64.c 2012-07-03 15:01:18.000000000 +0000
++++ mpfr-3.1.1-b/src/get_d64.c 2012-08-30 09:28:51.000000000 +0000
+@@ -32,6 +32,10 @@
+
+ #ifdef MPFR_WANT_DECIMAL_FLOATS
+
++#ifndef DEC64_MAX
++# define DEC64_MAX 9.999999999999999E384dd
++#endif
++
+ #ifdef DPD_FORMAT
+ static int T[1000] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
+@@ -142,26 +146,14 @@
+ static _Decimal64
+ get_decimal64_min (int negative)
+ {
+- union ieee_double_extract x;
+-
+- x.s.sig = (negative) ? 1 : 0;
+- x.s.exp = 0;
+- x.s.manh = 0;
+- x.s.manl = 1;
+- return x.d;
++ return negative ? - 1E-398dd : 1E-398dd;
+ }
+
+ /* construct the decimal64 largest finite number with given sign */
+ static _Decimal64
+ get_decimal64_max (int negative)
+ {
+- union ieee_double_extract x;
+-
+- x.s.sig = (negative) ? 1 : 0;
+- x.s.exp = 1919;
+- x.s.manh = 1048575; /* 2^20-1 */
+- x.s.manl = ~0;
+- return x.d;
++ return negative ? - DEC64_MAX : DEC64_MAX;
+ }
+
+ /* one-to-one conversion:
+@@ -334,7 +326,8 @@
+ /* the largest decimal64 number is just below 10^(385) < 2^1279 */
+ else if (MPFR_UNLIKELY (e > 1279)) /* then src >= 2^1279 */
+ {
+- if (MPFR_RNDZ || (rnd_mode == MPFR_RNDU && negative != 0)
++ if (rnd_mode == MPFR_RNDZ
++ || (rnd_mode == MPFR_RNDU && negative != 0)
+ || (rnd_mode == MPFR_RNDD && negative == 0))
+ return get_decimal64_max (negative);
+ else
+@@ -354,6 +347,15 @@
+ which corresponds to s=[0.]1000...000 and e=-397 */
+ if (e < -397)
+ {
++ if (rnd_mode == MPFR_RNDN && e == -398)
++ {
++ /* If 0.5E-398 < |src| < 1E-398 (smallest subnormal),
++ src should round to +/- 1E-398 in MPFR_RNDN. */
++ mpfr_get_str (s, &e, 10, 1, src, MPFR_RNDA);
++ return e == -398 && s[negative] <= '5' ?
++ get_decimal64_zero (negative) :
++ get_decimal64_min (negative);
++ }
+ if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
+ || (rnd_mode == MPFR_RNDD && negative == 0)
+ || (rnd_mode == MPFR_RNDU && negative != 0))
+@@ -379,7 +381,8 @@
+ which corresponds to s=[0.]9999...999 and e=385 */
+ else if (e > 385)
+ {
+- if (MPFR_RNDZ || (rnd_mode == MPFR_RNDU && negative != 0)
++ if (rnd_mode == MPFR_RNDZ
++ || (rnd_mode == MPFR_RNDU && negative != 0)
+ || (rnd_mode == MPFR_RNDD && negative == 0))
+ return get_decimal64_max (negative);
+ else
+diff -Naurd mpfr-3.1.1-a/src/mpfr.h mpfr-3.1.1-b/src/mpfr.h
+--- mpfr-3.1.1-a/src/mpfr.h 2012-07-03 15:01:19.000000000 +0000
++++ mpfr-3.1.1-b/src/mpfr.h 2012-08-30 09:28:51.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.1.1"
++#define MPFR_VERSION_STRING "3.1.1-p1"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.1-a/src/version.c mpfr-3.1.1-b/src/version.c
+--- mpfr-3.1.1-a/src/version.c 2012-07-03 15:01:18.000000000 +0000
++++ mpfr-3.1.1-b/src/version.c 2012-08-30 09:28:51.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.1";
++ return "3.1.1-p1";
+ }
+diff -Naurd mpfr-3.1.1-a/tests/tget_set_d64.c mpfr-3.1.1-b/tests/tget_set_d64.c
+--- mpfr-3.1.1-a/tests/tget_set_d64.c 2012-07-03 15:01:24.000000000 +0000
++++ mpfr-3.1.1-b/tests/tget_set_d64.c 2012-08-30 09:28:51.000000000 +0000
+@@ -25,6 +25,10 @@
+ #include <stdlib.h> /* for exit */
+ #include "mpfr-test.h"
+
++#ifndef DEC64_MAX
++# define DEC64_MAX 9.999999999999999E384dd
++#endif
++
+ /* #define DEBUG */
+
+ static void
+@@ -149,6 +153,15 @@
+ mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
+ mpfr_set (y, x, MPFR_RNDZ);
+ d = mpfr_get_decimal64 (x, MPFR_RNDU);
++ ASSERT_ALWAYS (d == DEC64_MAX);
++ mpfr_set_ui (x, 0, MPFR_RNDZ);
++ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
++ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
++
++ mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ);
++ mpfr_set (y, x, MPFR_RNDZ);
++ d = mpfr_get_decimal64 (x, MPFR_RNDA);
++ ASSERT_ALWAYS (d == -DEC64_MAX);
+ mpfr_set_ui (x, 0, MPFR_RNDZ);
+ mpfr_set_decimal64 (x, d, MPFR_RNDZ);
+ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
+@@ -225,6 +238,83 @@
+ mpfr_clear (x);
+ }
+
++static void
++check_overflow (void)
++{
++ mpfr_t x;
++ int err = 0, neg, rnd;
++
++ mpfr_init2 (x, 96);
++ for (neg = 0; neg < 2; neg++)
++ RND_LOOP (rnd)
++ {
++ _Decimal64 d, e;
++ mpfr_rnd_t r = (mpfr_rnd_t) rnd;
++ int sign = neg ? -1 : 1;
++
++ e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX;
++ /* This tests the binary exponent e > 1279 case of get_d64.c */
++ mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN);
++ d = mpfr_get_decimal64 (x, r);
++ if (d != e)
++ {
++ printf ("Error 1 in check_overflow for %s, %s\n",
++ neg ? "negative" : "positive",
++ mpfr_print_rnd_mode (r));
++ err = 1;
++ }
++ /* This tests the decimal exponent e > 385 case of get_d64.c */
++ mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN);
++ d = mpfr_get_decimal64 (x, r);
++ if (d != e)
++ {
++ printf ("Error 2 in check_overflow for %s, %s\n",
++ neg ? "negative" : "positive",
++ mpfr_print_rnd_mode (r));
++ err = 1;
++ }
++ /* This tests the last else (-382 <= e <= 385) of get_d64.c */
++ mpfr_set_decimal64 (x, e, MPFR_RNDA);
++ d = mpfr_get_decimal64 (x, r);
++ if (d != e)
++ {
++ printf ("Error 3 in check_overflow for %s, %s\n",
++ neg ? "negative" : "positive",
++ mpfr_print_rnd_mode (r));
++ err = 1;
++ }
++ }
++ mpfr_clear (x);
++ if (err)
++ exit (1);
++}
++
++static void
++check_tiny (void)
++{
++ mpfr_t x;
++ _Decimal64 d;
++
++ /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round
++ to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between
++ 0 and 1E-398 is not a representable binary number, so that there
++ are no tests for it. */
++ mpfr_init2 (x, 128);
++ mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ);
++ d = mpfr_get_decimal64 (x, MPFR_RNDN);
++ MPFR_ASSERTN (d == 1.0E-398dd);
++ mpfr_neg (x, x, MPFR_RNDN);
++ d = mpfr_get_decimal64 (x, MPFR_RNDN);
++ MPFR_ASSERTN (d == -1.0E-398dd);
++ mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU);
++ d = mpfr_get_decimal64 (x, MPFR_RNDN);
++ MPFR_ASSERTN (d == 1.0E-398dd);
++ mpfr_neg (x, x, MPFR_RNDN);
++ d = mpfr_get_decimal64 (x, MPFR_RNDN);
++ MPFR_ASSERTN (d == -1.0E-398dd);
++ mpfr_clear (x);
++}
++
+ int
+ main (void)
+ {
+@@ -241,6 +331,8 @@
+ check_inf_nan ();
+ check_random ();
+ check_native ();
++ check_overflow ();
++ check_tiny ();
+
+ tests_end_mpfr ();
+ return 0;
diff --git a/patches/mpfr/3.1.1/120-strtofr-ternary-value.patch b/patches/mpfr/3.1.1/120-strtofr-ternary-value.patch
new file mode 100644
index 0000000..76dbc45
--- /dev/null
+++ b/patches/mpfr/3.1.1/120-strtofr-ternary-value.patch
@@ -0,0 +1,170 @@
+diff -Naurd mpfr-3.1.1-a/PATCHES mpfr-3.1.1-b/PATCHES
+--- mpfr-3.1.1-a/PATCHES 2012-08-30 09:35:12.000000000 +0000
++++ mpfr-3.1.1-b/PATCHES 2012-08-30 09:35:12.000000000 +0000
+@@ -0,0 +1 @@
++strtofr-ternary-value
+diff -Naurd mpfr-3.1.1-a/VERSION mpfr-3.1.1-b/VERSION
+--- mpfr-3.1.1-a/VERSION 2012-08-30 09:28:51.000000000 +0000
++++ mpfr-3.1.1-b/VERSION 2012-08-30 09:35:12.000000000 +0000
+@@ -1 +1 @@
+-3.1.1-p1
++3.1.1-p2
+diff -Naurd mpfr-3.1.1-a/src/mpfr.h mpfr-3.1.1-b/src/mpfr.h
+--- mpfr-3.1.1-a/src/mpfr.h 2012-08-30 09:28:51.000000000 +0000
++++ mpfr-3.1.1-b/src/mpfr.h 2012-08-30 09:35:12.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.1.1-p1"
++#define MPFR_VERSION_STRING "3.1.1-p2"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.1-a/src/strtofr.c mpfr-3.1.1-b/src/strtofr.c
+--- mpfr-3.1.1-a/src/strtofr.c 2012-07-03 15:01:16.000000000 +0000
++++ mpfr-3.1.1-b/src/strtofr.c 2012-08-30 09:35:12.000000000 +0000
+@@ -667,6 +667,20 @@
+ /* (z, exp_z) = base^(exp_base-pstr_size) */
+ z = result + 2*ysize + 1;
+ err = mpfr_mpn_exp (z, &exp_z, pstr->base, exp_z, ysize);
++ /* Since we want y/z rounded toward zero, we must get an upper
++ bound of z. If err >= 0, the error on z is bounded by 2^err. */
++ if (err >= 0)
++ {
++ mp_limb_t cy;
++ unsigned long h = err / GMP_NUMB_BITS;
++ unsigned long l = err - h * GMP_NUMB_BITS;
++
++ if (h >= ysize) /* not enough precision in z */
++ goto next_loop;
++ cy = mpn_add_1 (z, z, ysize - h, MPFR_LIMB_ONE << l);
++ if (cy != 0) /* the code below requires z on ysize limbs */
++ goto next_loop;
++ }
+ exact = exact && (err == -1);
+ if (err == -2)
+ goto underflow; /* FIXME: Sure? */
+@@ -730,6 +744,7 @@
+ MPFR_RNDN, rnd, MPFR_PREC(x)))
+ break;
+
++ next_loop:
+ /* update the prec for next loop */
+ MPFR_ZIV_NEXT (loop, prec);
+ } /* loop */
+diff -Naurd mpfr-3.1.1-a/src/version.c mpfr-3.1.1-b/src/version.c
+--- mpfr-3.1.1-a/src/version.c 2012-08-30 09:28:51.000000000 +0000
++++ mpfr-3.1.1-b/src/version.c 2012-08-30 09:35:12.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.1-p1";
++ return "3.1.1-p2";
+ }
+diff -Naurd mpfr-3.1.1-a/tests/tstrtofr.c mpfr-3.1.1-b/tests/tstrtofr.c
+--- mpfr-3.1.1-a/tests/tstrtofr.c 2012-07-03 15:01:24.000000000 +0000
++++ mpfr-3.1.1-b/tests/tstrtofr.c 2012-08-30 09:35:12.000000000 +0000
+@@ -1105,6 +1105,92 @@
+ mpfr_clear (y);
+ }
+
++/* From a bug reported by Joseph S. Myers
++ https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */
++static void
++bug20120814 (void)
++{
++ mpfr_exp_t emin = -30, e;
++ mpfr_t x, y;
++ int r;
++ char s[64], *p;
++
++ mpfr_init2 (x, 2);
++ mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN);
++ mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD);
++ s[0] = s[1];
++ s[1] = '.';
++ for (p = s; *p != 0; p++) ;
++ *p = 'e';
++ sprintf (p + 1, "%d", (int) e - 1);
++
++ mpfr_init2 (y, 4);
++ r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN);
++ if (r <= 0 || ! mpfr_equal_p (x, y))
++ {
++ printf ("Error in bug20120814\n");
++ printf ("mpfr_strtofr failed on string \"%s\"\n", s);
++ printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin);
++ printf ("Got inex = %-6d and y = ", r);
++ mpfr_dump (y);
++ exit (1);
++ }
++
++ mpfr_clear (x);
++ mpfr_clear (y);
++}
++
++static void
++bug20120829 (void)
++{
++ mpfr_t x1, x2, e;
++ int inex1, inex2, i, r;
++ char s[48] = "1e-1";
++
++ mpfr_init2 (e, 128);
++ mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0);
++
++ inex1 = mpfr_set_si (e, -1, MPFR_RNDN);
++ MPFR_ASSERTN (inex1 == 0);
++
++ for (i = 1; i <= sizeof(s) - 5; i++)
++ {
++ s[3+i] = '0';
++ s[4+i] = 0;
++ inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN);
++ MPFR_ASSERTN (inex1 == 0);
++ RND_LOOP(r)
++ {
++ mpfr_rnd_t rnd = (mpfr_rnd_t) r;
++
++ inex1 = mpfr_exp10 (x1, e, rnd);
++ inex1 = SIGN (inex1);
++ inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd);
++ inex2 = SIGN (inex2);
++ /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do:
++ strtofr.c:...: MPFR assertion failed: cy == 0
++ r8396 is OK.
++ On 64-bit machines, for i = 15,
++ r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0)
++ r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize
++ r8394 and r8396 are OK.
++ */
++ if (! mpfr_equal_p (x1, x2) || inex1 != inex2)
++ {
++ printf ("Error in bug20120829 for i = %d, rnd = %s\n",
++ i, mpfr_print_rnd_mode (rnd));
++ printf ("Expected inex = %d, x = ", inex1);
++ mpfr_dump (x1);
++ printf ("Got inex = %d, x = ", inex2);
++ mpfr_dump (x2);
++ exit (1);
++ }
++ }
++ }
++
++ mpfr_clears (e, x1, x2, (mpfr_ptr) 0);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -1117,6 +1203,8 @@
+ check_retval ();
+ bug20081028 ();
+ test20100310 ();
++ bug20120814 ();
++ bug20120829 ();
+
+ tests_end_mpfr ();
+ return 0;
diff --git a/patches/mpfr/3.1.1/130-gmp51-compat.patch b/patches/mpfr/3.1.1/130-gmp51-compat.patch
new file mode 100644
index 0000000..ecf7537
--- /dev/null
+++ b/patches/mpfr/3.1.1/130-gmp51-compat.patch
@@ -0,0 +1,98 @@
+diff -Naurd mpfr-3.1.1-a/PATCHES mpfr-3.1.1-b/PATCHES
+--- mpfr-3.1.1-a/PATCHES 2013-02-22 12:17:27.000000000 +0000
++++ mpfr-3.1.1-b/PATCHES 2013-02-22 12:18:34.000000000 +0000
+@@ -0,0 +1 @@
++gmp51-compat
+diff -Naurd mpfr-3.1.1-a/VERSION mpfr-3.1.1-b/VERSION
+--- mpfr-3.1.1-a/VERSION 2012-08-30 09:35:12.000000000 +0000
++++ mpfr-3.1.1-b/VERSION 2013-02-22 12:18:20.000000000 +0000
+@@ -1 +1 @@
+-3.1.1-p2
++3.1.1-p3
+diff -Naurd mpfr-3.1.1-a/src/get_f.c mpfr-3.1.1-b/src/get_f.c
+--- mpfr-3.1.1-a/src/get_f.c 2012-07-03 15:01:19.000000000 +0000
++++ mpfr-3.1.1-b/src/get_f.c 2013-02-22 12:18:06.000000000 +0000
+@@ -61,7 +61,7 @@
+
+ sx = PREC (x);
+ SIZ (x) = sx;
+- xp = LIMBS (x);
++ xp = PTR (x);
+ for (i = 0; i < sx; i++)
+ xp[i] = MP_LIMB_T_MAX;
+
+diff -Naurd mpfr-3.1.1-a/src/mpfr-gmp.h mpfr-3.1.1-b/src/mpfr-gmp.h
+--- mpfr-3.1.1-a/src/mpfr-gmp.h 2012-07-03 15:01:16.000000000 +0000
++++ mpfr-3.1.1-b/src/mpfr-gmp.h 2013-02-22 12:18:06.000000000 +0000
+@@ -163,7 +163,6 @@
+ #define SIZ(x) ((x)->_mp_size)
+ #define ABSIZ(x) ABS (SIZ (x))
+ #define PTR(x) ((x)->_mp_d)
+-#define LIMBS(x) ((x)->_mp_d)
+ #define EXP(x) ((x)->_mp_exp)
+ #define PREC(x) ((x)->_mp_prec)
+ #define ALLOC(x) ((x)->_mp_alloc)
+diff -Naurd mpfr-3.1.1-a/src/mpfr.h mpfr-3.1.1-b/src/mpfr.h
+--- mpfr-3.1.1-a/src/mpfr.h 2012-08-30 09:35:12.000000000 +0000
++++ mpfr-3.1.1-b/src/mpfr.h 2013-02-22 12:18:20.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 1
+-#define MPFR_VERSION_STRING "3.1.1-p2"
++#define MPFR_VERSION_STRING "3.1.1-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.1-a/src/version.c mpfr-3.1.1-b/src/version.c
+--- mpfr-3.1.1-a/src/version.c 2012-08-30 09:35:12.000000000 +0000
++++ mpfr-3.1.1-b/src/version.c 2013-02-22 12:18:20.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.1-p2";
++ return "3.1.1-p3";
+ }
+diff -Naurd mpfr-3.1.1-a/tests/tadd.c mpfr-3.1.1-b/tests/tadd.c
+--- mpfr-3.1.1-a/tests/tadd.c 2012-07-03 15:01:24.000000000 +0000
++++ mpfr-3.1.1-b/tests/tadd.c 2013-02-22 12:18:06.000000000 +0000
+@@ -20,7 +20,7 @@
+ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+-#define NUM 30000
++#define N 30000
+
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -674,7 +674,7 @@
+
+ mpfr_init2 (one, MPFR_PREC_MIN);
+ mpfr_set_ui (one, 1, MPFR_RNDN);
+- for (n = 0; n < NUM; n++)
++ for (n = 0; n < N; n++)
+ {
+ mpfr_prec_t prec_a, prec_b, prec_c;
+ mpfr_exp_t tb=0, tc, diff;
+diff -Naurd mpfr-3.1.1-a/tests/tgeneric.c mpfr-3.1.1-b/tests/tgeneric.c
+--- mpfr-3.1.1-a/tests/tgeneric.c 2012-07-03 15:01:24.000000000 +0000
++++ mpfr-3.1.1-b/tests/tgeneric.c 2013-02-22 12:18:06.000000000 +0000
+@@ -121,7 +121,7 @@
+ #endif
+
+ static void
+-test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
++test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
+ {
+ mpfr_prec_t prec, xprec, yprec;
+ mpfr_t x, y, z, t, w;
+@@ -155,7 +155,7 @@
+ mpfr_set_prec (w, yprec);
+
+ /* Note: in precision p1, we test 4 special cases. */
+- for (n = 0; n < (prec == p1 ? N + 4 : N); n++)
++ for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
+ {
+ int infinite_input = 0;
+
diff --git a/patches/mpfr/3.1.2/110-exp_2.patch b/patches/mpfr/3.1.2/110-exp_2.patch
new file mode 100644
index 0000000..731ea92
--- /dev/null
+++ b/patches/mpfr/3.1.2/110-exp_2.patch
@@ -0,0 +1,45 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/PATCHES 2013-09-26 10:52:52.000000000 +0000
+@@ -0,0 +1 @@
++exp_2
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2013-03-13 15:37:28.000000000 +0000
++++ mpfr-3.1.2-b/VERSION 2013-09-26 10:52:52.000000000 +0000
+@@ -1 +1 @@
+-3.1.2
++3.1.2-p1
+diff -Naurd mpfr-3.1.2-a/src/exp_2.c mpfr-3.1.2-b/src/exp_2.c
+--- mpfr-3.1.2-a/src/exp_2.c 2013-03-13 15:37:28.000000000 +0000
++++ mpfr-3.1.2-b/src/exp_2.c 2013-09-26 10:52:52.000000000 +0000
+@@ -204,7 +204,7 @@
+ for (k = 0; k < K; k++)
+ {
+ mpz_mul (ss, ss, ss);
+- exps <<= 1;
++ exps *= 2;
+ exps += mpz_normalize (ss, ss, q);
+ }
+ mpfr_set_z (s, ss, MPFR_RNDN);
+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 2013-03-13 15:37:37.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2013-09-26 10:52:52.000000000 +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"
++#define MPFR_VERSION_STRING "3.1.2-p1"
+
+ /* 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 2013-03-13 15:37:34.000000000 +0000
++++ mpfr-3.1.2-b/src/version.c 2013-09-26 10:52:52.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2";
++ return "3.1.2-p1";
+ }
diff --git a/patches/mpfr/3.1.2/120-fits-smallneg.patch b/patches/mpfr/3.1.2/120-fits-smallneg.patch
new file mode 100644
index 0000000..b229c18
--- /dev/null
+++ b/patches/mpfr/3.1.2/120-fits-smallneg.patch
@@ -0,0 +1,605 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2013-09-26 10:56:55.000000000 +0000
++++ mpfr-3.1.2-b/PATCHES 2013-09-26 10:56:55.000000000 +0000
+@@ -0,0 +1 @@
++fits-smallneg
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/VERSION 2013-09-26 10:56:55.000000000 +0000
+@@ -1 +1 @@
+-3.1.2-p1
++3.1.2-p2
+diff -Naurd mpfr-3.1.2-a/src/fits_u.h mpfr-3.1.2-b/src/fits_u.h
+--- mpfr-3.1.2-a/src/fits_u.h 2013-03-13 15:37:35.000000000 +0000
++++ mpfr-3.1.2-b/src/fits_u.h 2013-09-26 10:56:55.000000000 +0000
+@@ -32,17 +32,20 @@
+ int res;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+- /* Zero always fit */
+- return MPFR_IS_ZERO (f) ? 1 : 0;
+- else if (MPFR_IS_NEG (f))
+- /* Negative numbers don't fit */
+- return 0;
+- /* now it fits if
+- (a) f <= MAXIMUM
+- (b) round(f, prec(slong), rnd) <= MAXIMUM */
++ return MPFR_IS_ZERO (f) ? 1 : 0; /* Zero always fits */
+
+ e = MPFR_GET_EXP (f);
+
++ if (MPFR_IS_NEG (f))
++ return e >= 1 ? 0 /* f <= -1 does not fit */
++ : rnd != MPFR_RNDN ? MPFR_IS_LIKE_RNDU (rnd, -1) /* directed mode */
++ : e < 0 ? 1 /* f > -1/2 fits in MPFR_RNDN */
++ : mpfr_powerof2_raw(f); /* -1/2 fits, -1 < f < -1/2 don't */
++
++ /* Now it fits if
++ (a) f <= MAXIMUM
++ (b) round(f, prec(slong), rnd) <= MAXIMUM */
++
+ /* first compute prec(MAXIMUM); fits in an int */
+ for (s = MAXIMUM, prec = 0; s != 0; s /= 2, prec ++);
+
+diff -Naurd mpfr-3.1.2-a/src/fits_uintmax.c mpfr-3.1.2-b/src/fits_uintmax.c
+--- mpfr-3.1.2-a/src/fits_uintmax.c 2013-03-13 15:37:33.000000000 +0000
++++ mpfr-3.1.2-b/src/fits_uintmax.c 2013-09-26 10:56:55.000000000 +0000
+@@ -27,51 +27,19 @@
+ #include "mpfr-intmax.h"
+ #include "mpfr-impl.h"
+
+-#ifdef _MPFR_H_HAVE_INTMAX_T
+-
+-/* We can't use fits_u.h <= mpfr_cmp_ui */
+-int
+-mpfr_fits_uintmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
+-{
+- mpfr_exp_t e;
+- int prec;
+- uintmax_t s;
+- mpfr_t x;
+- int res;
+-
+- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f)))
+- /* Zero always fit */
+- return MPFR_IS_ZERO (f) ? 1 : 0;
+- else if (MPFR_IS_NEG (f))
+- /* Negative numbers don't fit */
+- return 0;
+- /* now it fits if
+- (a) f <= MAXIMUM
+- (b) round(f, prec(slong), rnd) <= MAXIMUM */
+-
+- e = MPFR_GET_EXP (f);
+-
+- /* first compute prec(MAXIMUM); fits in an int */
+- for (s = MPFR_UINTMAX_MAX, prec = 0; s != 0; s /= 2, prec ++);
+-
+- /* MAXIMUM needs prec bits, i.e. MAXIMUM = 2^prec - 1 */
+-
+- /* if e <= prec - 1, then f < 2^(prec-1) < MAXIMUM */
+- if (e <= prec - 1)
+- return 1;
++/* Note: though mpfr-impl.h is included in fits_u.h, we also include it
++ above so that it gets included even when _MPFR_H_HAVE_INTMAX_T is not
++ defined; this is necessary to avoid an empty translation unit, which
++ is forbidden by ISO C. Without this, a failing test can be reproduced
++ by creating an invalid stdint.h somewhere in the default include path
++ and by compiling MPFR with "gcc -ansi -pedantic-errors". */
+
+- /* if e >= prec + 1, then f >= 2^prec > MAXIMUM */
+- if (e >= prec + 1)
+- return 0;
++#ifdef _MPFR_H_HAVE_INTMAX_T
+
+- MPFR_ASSERTD (e == prec);
++#define FUNCTION mpfr_fits_uintmax_p
++#define MAXIMUM MPFR_UINTMAX_MAX
++#define TYPE uintmax_t
+
+- /* hard case: first round to prec bits, then check */
+- mpfr_init2 (x, prec);
+- mpfr_set (x, f, rnd);
+- res = MPFR_GET_EXP (x) == e;
+- mpfr_clear (x);
+- return res;
+-}
++#include "fits_u.h"
+
+ #endif
+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 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2013-09-26 10:56:55.000000000 +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-p1"
++#define MPFR_VERSION_STRING "3.1.2-p2"
+
+ /* 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 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/src/version.c 2013-09-26 10:56:55.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p1";
++ return "3.1.2-p2";
+ }
+diff -Naurd mpfr-3.1.2-a/tests/tfits.c mpfr-3.1.2-b/tests/tfits.c
+--- mpfr-3.1.2-a/tests/tfits.c 2013-03-13 15:37:45.000000000 +0000
++++ mpfr-3.1.2-b/tests/tfits.c 2013-09-26 10:56:55.000000000 +0000
+@@ -33,155 +33,176 @@
+ #include "mpfr-intmax.h"
+ #include "mpfr-test.h"
+
+-#define ERROR1 { printf("Initial error for x="); mpfr_dump(x); exit(1); }
+-#define ERROR2 { printf("Error for x="); mpfr_dump(x); exit(1); }
++#define ERROR1(N) \
++ do \
++ { \
++ printf("Error %d for rnd = %s and x = ", N, \
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \
++ mpfr_dump(x); \
++ exit(1); \
++ } \
++ while (0)
+
+ static void check_intmax (void);
+
+ int
+ main (void)
+ {
+- mpfr_t x;
++ mpfr_t x, y;
++ int i, r;
+
+ tests_start_mpfr ();
+
+ mpfr_init2 (x, 256);
++ mpfr_init2 (y, 8);
+
+- /* Check NAN */
+- mpfr_set_nan (x);
+- if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR1;
++ RND_LOOP (r)
++ {
+
+- /* Check INF */
+- mpfr_set_inf (x, 1);
+- if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check NAN */
++ mpfr_set_nan (x);
++ if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (1);
++ if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (2);
++ if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (3);
++ if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (4);
++ if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (5);
++ if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (6);
+
+- /* Check Zero */
+- MPFR_SET_ZERO (x);
+- if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check INF */
++ mpfr_set_inf (x, 1);
++ if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (7);
++ if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (8);
++ if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (9);
++ if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (10);
++ if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (11);
++ if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (12);
+
+- /* Check small op */
+- mpfr_set_str1 (x, "1@-1");
+- if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check Zero */
++ MPFR_SET_ZERO (x);
++ if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (13);
++ if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (14);
++ if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (15);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (16);
++ if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (17);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (18);
+
+- /* Check 17 */
+- mpfr_set_ui (x, 17, MPFR_RNDN);
+- if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check small positive op */
++ mpfr_set_str1 (x, "1@-1");
++ if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (19);
++ if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (20);
++ if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (21);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (22);
++ if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (23);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (24);
+
+- /* Check all other values */
+- mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+- mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR1;
+- mpfr_mul_2exp (x, x, 40, MPFR_RNDN);
+- if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check 17 */
++ mpfr_set_ui (x, 17, MPFR_RNDN);
++ if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (25);
++ if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (26);
++ if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (27);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (28);
++ if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (29);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (30);
+
+- mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+- if (!mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_ui (x, LONG_MAX, MPFR_RNDN);
+- if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_ui (x, UINT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_ui (x, INT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_ui (x, USHRT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_ui (x, SHRT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check all other values */
++ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
++ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
++ if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (31);
++ if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (32);
++ mpfr_mul_2exp (x, x, 40, MPFR_RNDN);
++ if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (33);
++ if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (34);
++ if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (35);
++ if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (36);
++ if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (37);
+
+- mpfr_set_si (x, 1, MPFR_RNDN);
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
++ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
++ if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (38);
++ mpfr_set_ui (x, LONG_MAX, MPFR_RNDN);
++ if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (39);
++ mpfr_set_ui (x, UINT_MAX, MPFR_RNDN);
++ if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (40);
++ mpfr_set_ui (x, INT_MAX, MPFR_RNDN);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (41);
++ mpfr_set_ui (x, USHRT_MAX, MPFR_RNDN);
++ if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (42);
++ mpfr_set_ui (x, SHRT_MAX, MPFR_RNDN);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (43);
+
+- /* Check negative value */
+- mpfr_set_si (x, -1, MPFR_RNDN);
+- if (!mpfr_fits_sint_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_sshort_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_slong_p (x, MPFR_RNDN))
+- ERROR2;
+- if (mpfr_fits_uint_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_ushort_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_ulong_p (x, MPFR_RNDN))
+- ERROR1;
++ mpfr_set_si (x, 1, MPFR_RNDN);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (44);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (45);
++
++ /* Check negative op */
++ for (i = 1; i <= 4; i++)
++ {
++ int inv;
++
++ mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
++ mpfr_rint (y, x, (mpfr_rnd_t) r);
++ inv = MPFR_NOTZERO (y);
++ if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r) ^ inv)
++ ERROR1 (46);
++ if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
++ ERROR1 (47);
++ if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r) ^ inv)
++ ERROR1 (48);
++ if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
++ ERROR1 (49);
++ if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r) ^ inv)
++ ERROR1 (50);
++ if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
++ ERROR1 (51);
++ }
++ }
+
+ mpfr_clear (x);
++ mpfr_clear (y);
+
+ check_intmax ();
+
+@@ -189,85 +210,98 @@
+ return 0;
+ }
+
+-static void check_intmax (void)
++static void
++check_intmax (void)
+ {
+ #ifdef _MPFR_H_HAVE_INTMAX_T
+- mpfr_t x;
++ mpfr_t x, y;
++ int i, r;
+
+- mpfr_init2 (x, sizeof (uintmax_t)*CHAR_BIT);
++ mpfr_init2 (x, sizeof (uintmax_t) * CHAR_BIT);
++ mpfr_init2 (y, 8);
+
+- /* Check NAN */
+- mpfr_set_nan (x);
+- if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR1;
++ RND_LOOP (r)
++ {
++ /* Check NAN */
++ mpfr_set_nan (x);
++ if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (52);
++ if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (53);
+
+- /* Check INF */
+- mpfr_set_inf (x, 1);
+- if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check INF */
++ mpfr_set_inf (x, 1);
++ if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (54);
++ if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (55);
+
+- /* Check Zero */
+- MPFR_SET_ZERO (x);
+- if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check Zero */
++ MPFR_SET_ZERO (x);
++ if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (56);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (57);
+
+- /* Check small op */
+- mpfr_set_str1 (x, "1@-1");
+- if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check positive small op */
++ mpfr_set_str1 (x, "1@-1");
++ if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (58);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (59);
+
+- /* Check 17 */
+- mpfr_set_ui (x, 17, MPFR_RNDN);
+- if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR2;
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
++ /* Check 17 */
++ mpfr_set_ui (x, 17, MPFR_RNDN);
++ if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (60);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (61);
+
+- /* Check hugest */
+- mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
+- if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR1;
+- if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check hugest */
++ mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
++ if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (62);
++ if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (63);
+
+- /* Check all other values */
+- mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+- mpfr_add_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR1;
+- mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+- if (!mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+- mpfr_add_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR1;
+- mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
+- mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check all other values */
++ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
++ mpfr_add_ui (x, x, 1, MPFR_RNDN);
++ if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (64);
++ mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
++ if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (65);
++ mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
++ mpfr_add_ui (x, x, 1, MPFR_RNDN);
++ if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (66);
++ mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (67);
++ mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (68);
++ mpfr_sub_ui (x, x, 1, MPFR_RNDN);
++ if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (69);
+
+- /* Check negative value */
+- mpfr_set_si (x, -1, MPFR_RNDN);
+- if (!mpfr_fits_intmax_p (x, MPFR_RNDN))
+- ERROR2;
+- if (mpfr_fits_uintmax_p (x, MPFR_RNDN))
+- ERROR1;
++ /* Check negative op */
++ for (i = 1; i <= 4; i++)
++ {
++ int inv;
++
++ mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
++ mpfr_rint (y, x, (mpfr_rnd_t) r);
++ inv = MPFR_NOTZERO (y);
++ if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r) ^ inv)
++ ERROR1 (70);
++ if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
++ ERROR1 (71);
++ }
++ }
+
+ mpfr_clear (x);
++ mpfr_clear (y);
+ #endif
+ }
+-
diff --git a/patches/mpfr/3.1.2/130-clang-divby0.patch b/patches/mpfr/3.1.2/130-clang-divby0.patch
new file mode 100644
index 0000000..8e0cd8e
--- /dev/null
+++ b/patches/mpfr/3.1.2/130-clang-divby0.patch
@@ -0,0 +1,129 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2013-10-09 13:34:21.000000000 +0000
++++ mpfr-3.1.2-b/PATCHES 2013-10-09 13:34:21.000000000 +0000
+@@ -0,0 +1 @@
++clang-divby0
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/VERSION 2013-10-09 13:34:21.000000000 +0000
+@@ -1 +1 @@
+-3.1.2-p2
++3.1.2-p3
+diff -Naurd mpfr-3.1.2-a/src/mpfr-impl.h mpfr-3.1.2-b/src/mpfr-impl.h
+--- mpfr-3.1.2-a/src/mpfr-impl.h 2013-03-13 15:37:36.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr-impl.h 2013-10-09 13:34:21.000000000 +0000
+@@ -468,8 +468,16 @@
+ #define MPFR_LIMBS_PER_FLT ((IEEE_FLT_MANT_DIG-1)/GMP_NUMB_BITS+1)
+
+ /* Visual C++ doesn't support +1.0/0.0, -1.0/0.0 and 0.0/0.0
+- at compile time. */
+-#if defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)
++ at compile time.
++ Clang with -fsanitize=undefined is a bit similar due to a bug:
++ http://llvm.org/bugs/show_bug.cgi?id=17381
++ but even without its sanitizer, it may be better to use the
++ double_zero version until IEEE 754 division by zero is properly
++ supported:
++ http://llvm.org/bugs/show_bug.cgi?id=17000
++*/
++#if (defined(_MSC_VER) && defined(_WIN32) && (_MSC_VER >= 1200)) || \
++ defined(__clang__)
+ static double double_zero = 0.0;
+ # define DBL_NAN (double_zero/double_zero)
+ # define DBL_POS_INF ((double) 1.0/double_zero)
+@@ -501,6 +509,8 @@
+ (with Xcode 2.4.1, i.e. the latest one). */
+ #define LVALUE(x) (&(x) == &(x) || &(x) != &(x))
+ #define DOUBLE_ISINF(x) (LVALUE(x) && ((x) > DBL_MAX || (x) < -DBL_MAX))
++/* The DOUBLE_ISNAN(x) macro is also valid on long double x
++ (assuming that the compiler isn't too broken). */
+ #ifdef MPFR_NANISNAN
+ /* Avoid MIPSpro / IRIX64 / gcc -ffast-math (incorrect) optimizations.
+ The + must not be replaced by a ||. With gcc -ffast-math, NaN is
+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 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2013-10-09 13:34:21.000000000 +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-p2"
++#define MPFR_VERSION_STRING "3.1.2-p3"
+
+ /* 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 2013-09-26 10:52:52.000000000 +0000
++++ mpfr-3.1.2-b/src/version.c 2013-10-09 13:34:21.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p2";
++ return "3.1.2-p3";
+ }
+diff -Naurd mpfr-3.1.2-a/tests/tget_flt.c mpfr-3.1.2-b/tests/tget_flt.c
+--- mpfr-3.1.2-a/tests/tget_flt.c 2013-03-13 15:37:44.000000000 +0000
++++ mpfr-3.1.2-b/tests/tget_flt.c 2013-10-09 13:34:21.000000000 +0000
+@@ -28,9 +28,17 @@
+ main (void)
+ {
+ mpfr_t x, y;
+- float f, g, infp;
++ float f, g;
+ int i;
++#if !defined(MPFR_ERRDIVZERO)
++ float infp;
++#endif
++
++ tests_start_mpfr ();
+
++#if !defined(MPFR_ERRDIVZERO)
++ /* The definition of DBL_POS_INF involves a division by 0. This makes
++ "clang -O2 -fsanitize=undefined -fno-sanitize-recover" fail. */
+ infp = (float) DBL_POS_INF;
+ if (infp * 0.5 != infp)
+ {
+@@ -38,8 +46,7 @@
+ fprintf (stderr, "(this is probably a compiler bug, please report)\n");
+ exit (1);
+ }
+-
+- tests_start_mpfr ();
++#endif
+
+ mpfr_init2 (x, 24);
+ mpfr_init2 (y, 24);
+@@ -353,6 +360,7 @@
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
++#if !defined(MPFR_ERRDIVZERO)
+ f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
+ thus we should get +Inf */
+ g = infp;
+@@ -376,6 +384,7 @@
+ printf ("expected %.8e, got %.8e\n", g, f);
+ exit (1);
+ }
++#endif
+
+ mpfr_clear (x);
+ mpfr_clear (y);
+diff -Naurd mpfr-3.1.2-a/tests/tset_ld.c mpfr-3.1.2-b/tests/tset_ld.c
+--- mpfr-3.1.2-a/tests/tset_ld.c 2013-03-13 15:37:44.000000000 +0000
++++ mpfr-3.1.2-b/tests/tset_ld.c 2013-10-09 13:34:21.000000000 +0000
+@@ -47,8 +47,11 @@
+ static int
+ Isnan_ld (long double d)
+ {
+- double e = (double) d;
+- if (DOUBLE_ISNAN (e))
++ /* Do not convert d to double as this can give an overflow, which
++ may confuse compilers without IEEE 754 support (such as clang
++ -fsanitize=undefined), or trigger a trap if enabled.
++ The DOUBLE_ISNAN macro should work fine on long double. */
++ if (DOUBLE_ISNAN (d))
+ return 1;
+ LONGDOUBLE_NAN_ACTION (d, goto yes);
+ return 0;
diff --git a/patches/mpfr/3.1.2/140-printf-alt0.patch b/patches/mpfr/3.1.2/140-printf-alt0.patch
new file mode 100644
index 0000000..2451f36
--- /dev/null
+++ b/patches/mpfr/3.1.2/140-printf-alt0.patch
@@ -0,0 +1,84 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2013-11-15 00:51:49.211333830 +0000
++++ mpfr-3.1.2-b/PATCHES 2013-11-15 00:51:49.323334999 +0000
+@@ -0,0 +1 @@
++printf-alt0
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2013-11-15 00:51:49.211333830 +0000
++++ mpfr-3.1.2-b/VERSION 2013-11-15 00:51:49.323334999 +0000
+@@ -1 +1 @@
+-3.1.2-p3
++3.1.2-p4
+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 2013-11-15 00:51:49.211333830 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2013-11-15 00:51:49.323334999 +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-p3"
++#define MPFR_VERSION_STRING "3.1.2-p4"
+
+ /* 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/vasprintf.c mpfr-3.1.2-b/src/vasprintf.c
+--- mpfr-3.1.2-a/src/vasprintf.c 2013-03-13 15:37:37.000000000 +0000
++++ mpfr-3.1.2-b/src/vasprintf.c 2013-11-15 00:51:49.267334408 +0000
+@@ -1040,7 +1040,7 @@
+ }
+
+ /* Determine the different parts of the string representation of the regular
+- number P when SPEC.SPEC is 'e', 'E', 'g', or 'G'.
++ number P when spec.spec is 'e', 'E', 'g', or 'G'.
+ DEC_INFO contains the previously computed exponent and string or is NULL.
+
+ return -1 if some field > INT_MAX */
+@@ -1167,7 +1167,7 @@
+ }
+
+ /* Determine the different parts of the string representation of the regular
+- number P when SPEC.SPEC is 'f', 'F', 'g', or 'G'.
++ number P when spec.spec is 'f', 'F', 'g', or 'G'.
+ DEC_INFO contains the previously computed exponent and string or is NULL.
+
+ return -1 if some field of number_parts is greater than INT_MAX */
+@@ -1559,7 +1559,7 @@
+ /* fractional part */
+ {
+ np->point = MPFR_DECIMAL_POINT;
+- np->fp_trailing_zeros = (spec.spec == 'g' && spec.spec == 'G') ?
++ np->fp_trailing_zeros = (spec.spec == 'g' || spec.spec == 'G') ?
+ spec.prec - 1 : spec.prec;
+ }
+ else if (spec.alt)
+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 2013-11-15 00:51:49.211333830 +0000
++++ mpfr-3.1.2-b/src/version.c 2013-11-15 00:51:49.323334999 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p3";
++ return "3.1.2-p4";
+ }
+diff -Naurd mpfr-3.1.2-a/tests/tsprintf.c mpfr-3.1.2-b/tests/tsprintf.c
+--- mpfr-3.1.2-a/tests/tsprintf.c 2013-03-13 15:37:44.000000000 +0000
++++ mpfr-3.1.2-b/tests/tsprintf.c 2013-11-15 00:51:49.267334408 +0000
+@@ -456,10 +456,16 @@
+ check_sprintf ("1.999900 ", "%-#10.7RG", x);
+ check_sprintf ("1.9999 ", "%-10.7RG", x);
+ mpfr_set_ui (x, 1, MPFR_RNDN);
++ check_sprintf ("1.", "%#.1Rg", x);
++ check_sprintf ("1. ", "%-#5.1Rg", x);
++ check_sprintf (" 1.0", "%#5.2Rg", x);
+ check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x);
+ check_sprintf ("1", "%.30Rg", x);
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+- check_sprintf ("0.000000000000000000000000000000", "%#.30Rg", x);
++ check_sprintf ("0.", "%#.1Rg", x);
++ check_sprintf ("0. ", "%-#5.1Rg", x);
++ check_sprintf (" 0.0", "%#5.2Rg", x);
++ check_sprintf ("0.00000000000000000000000000000", "%#.30Rg", x);
+ check_sprintf ("0", "%.30Rg", x);
+
+ /* following tests with precision 53 bits */
diff --git a/patches/mpfr/3.1.2/150-custom_init_set.patch b/patches/mpfr/3.1.2/150-custom_init_set.patch
new file mode 100644
index 0000000..669b91d
--- /dev/null
+++ b/patches/mpfr/3.1.2/150-custom_init_set.patch
@@ -0,0 +1,42 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2013-12-01 11:07:49.575329762 +0000
++++ mpfr-3.1.2-b/PATCHES 2013-12-01 11:07:49.751331625 +0000
+@@ -0,0 +1 @@
++custom_init_set
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2013-12-01 11:07:49.571329714 +0000
++++ mpfr-3.1.2-b/VERSION 2013-12-01 11:07:49.747331585 +0000
+@@ -1 +1 @@
+-3.1.2-p4
++3.1.2-p5
+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 2013-12-01 11:07:49.571329714 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2013-12-01 11:07:49.747331585 +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-p4"
++#define MPFR_VERSION_STRING "3.1.2-p5"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -861,7 +861,7 @@
+ _t = (mpfr_kind_t) _k; \
+ _s = 1; \
+ } else { \
+- _t = (mpfr_kind_t) -k; \
++ _t = (mpfr_kind_t) - _k; \
+ _s = -1; \
+ } \
+ _e = _t == MPFR_REGULAR_KIND ? (e) : \
+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 2013-12-01 11:07:49.575329762 +0000
++++ mpfr-3.1.2-b/src/version.c 2013-12-01 11:07:49.747331585 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p4";
++ return "3.1.2-p5";
+ }
diff --git a/patches/mpfr/3.1.2/160-li2-return.patch b/patches/mpfr/3.1.2/160-li2-return.patch
new file mode 100644
index 0000000..50cd04d
--- /dev/null
+++ b/patches/mpfr/3.1.2/160-li2-return.patch
@@ -0,0 +1,43 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2014-04-15 21:56:49.609057464 +0000
++++ mpfr-3.1.2-b/PATCHES 2014-04-15 21:56:49.697059857 +0000
+@@ -0,0 +1 @@
++li2-return
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2014-04-15 21:56:49.609057464 +0000
++++ mpfr-3.1.2-b/VERSION 2014-04-15 21:56:49.697059857 +0000
+@@ -1 +1 @@
+-3.1.2-p5
++3.1.2-p6
+diff -Naurd mpfr-3.1.2-a/src/li2.c mpfr-3.1.2-b/src/li2.c
+--- mpfr-3.1.2-a/src/li2.c 2013-03-13 15:37:32.000000000 +0000
++++ mpfr-3.1.2-b/src/li2.c 2014-04-15 21:56:49.653058661 +0000
+@@ -630,5 +630,5 @@
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
+
+- MPFR_ASSERTN (0); /* should never reach this point */
++ MPFR_RET_NEVER_GO_HERE ();
+ }
+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-04-15 21:56:49.609057464 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2014-04-15 21:56:49.697059857 +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-p5"
++#define MPFR_VERSION_STRING "3.1.2-p6"
+
+ /* 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-04-15 21:56:49.609057464 +0000
++++ mpfr-3.1.2-b/src/version.c 2014-04-15 21:56:49.697059857 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p5";
++ return "3.1.2-p6";
+ }
diff --git a/patches/mpfr/3.1.2/170-exp3.patch b/patches/mpfr/3.1.2/170-exp3.patch
new file mode 100644
index 0000000..378c3bf
--- /dev/null
+++ b/patches/mpfr/3.1.2/170-exp3.patch
@@ -0,0 +1,71 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2014-04-15 22:04:57.090286262 +0000
++++ mpfr-3.1.2-b/PATCHES 2014-04-15 22:04:57.162288198 +0000
+@@ -0,0 +1 @@
++exp3
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2014-04-15 22:04:57.086286154 +0000
++++ mpfr-3.1.2-b/VERSION 2014-04-15 22:04:57.162288198 +0000
+@@ -1 +1 @@
+-3.1.2-p6
++3.1.2-p7
+diff -Naurd mpfr-3.1.2-a/src/exp3.c mpfr-3.1.2-b/src/exp3.c
+--- mpfr-3.1.2-a/src/exp3.c 2013-03-13 15:37:34.000000000 +0000
++++ mpfr-3.1.2-b/src/exp3.c 2014-04-15 22:04:57.126287230 +0000
+@@ -283,7 +283,7 @@
+ }
+ }
+
+- if (mpfr_can_round (shift_x > 0 ? t : tmp, realprec, MPFR_RNDD, MPFR_RNDZ,
++ if (mpfr_can_round (shift_x > 0 ? t : tmp, realprec, MPFR_RNDN, MPFR_RNDZ,
+ MPFR_PREC(y) + (rnd_mode == MPFR_RNDN)))
+ {
+ inexact = mpfr_set (y, shift_x > 0 ? t : tmp, rnd_mode);
+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-04-15 22:04:57.086286154 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2014-04-15 22:04:57.162288198 +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-p6"
++#define MPFR_VERSION_STRING "3.1.2-p7"
+
+ /* 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-04-15 22:04:57.090286262 +0000
++++ mpfr-3.1.2-b/src/version.c 2014-04-15 22:04:57.162288198 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p6";
++ return "3.1.2-p7";
+ }
+diff -Naurd mpfr-3.1.2-a/tests/texp.c mpfr-3.1.2-b/tests/texp.c
+--- mpfr-3.1.2-a/tests/texp.c 2013-03-13 15:37:44.000000000 +0000
++++ mpfr-3.1.2-b/tests/texp.c 2014-04-15 22:04:57.126287230 +0000
+@@ -150,6 +150,22 @@
+ exit (1);
+ }
+
++ mpfr_set_prec (x, 118);
++ mpfr_set_str_binary (x, "0.1110010100011101010000111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-86");
++ mpfr_set_prec (y, 118);
++ mpfr_exp_2 (y, x, MPFR_RNDU);
++ mpfr_exp_3 (x, x, MPFR_RNDU);
++ if (mpfr_cmp (x, y))
++ {
++ printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=118\n");
++ printf ("mpfr_exp_2 gives ");
++ mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
++ printf ("\nmpfr_exp_3 gives ");
++ mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++
+ mpfr_clear (x);
+ mpfr_clear (y);
+ return 0;
diff --git a/patches/mpfr/3.1.2/180-gmp6-compat.patch b/patches/mpfr/3.1.2/180-gmp6-compat.patch
new file mode 100644
index 0000000..2245c7c
--- /dev/null
+++ b/patches/mpfr/3.1.2/180-gmp6-compat.patch
@@ -0,0 +1,254 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2014-04-15 22:20:32.243481506 +0000
++++ mpfr-3.1.2-b/PATCHES 2014-04-15 22:22:32.418722707 +0000
+@@ -0,0 +1 @@
++gmp6-compat
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2014-04-15 22:20:20.755171478 +0000
++++ mpfr-3.1.2-b/VERSION 2014-04-15 22:21:45.225450147 +0000
+@@ -1 +1 @@
+-3.1.2-p7
++3.1.2-p8
+diff -Naurd mpfr-3.1.2-a/configure mpfr-3.1.2-b/configure
+--- mpfr-3.1.2-a/configure 2013-03-13 15:38:20.000000000 +0000
++++ mpfr-3.1.2-b/configure 2014-04-15 22:21:38.821277476 +0000
+@@ -14545,26 +14545,30 @@
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+
+-if test "$use_gmp_build" = yes ; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for valid GMP_NUMB_BITS" >&5
+-$as_echo_n "checking for valid GMP_NUMB_BITS... " >&6; }
+- if test "$cross_compiling" = yes; then :
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMP_NUMB_BITS and sizeof(mp_limb_t) consistency" >&5
++$as_echo_n "checking for GMP_NUMB_BITS and sizeof(mp_limb_t) consistency... " >&6; }
++if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: can't test" >&5
+ $as_echo "can't test" >&6; }
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
++#include <stdio.h>
+ #include <limits.h>
+ #include "gmp.h"
+-#include "gmp-impl.h"
+
+ int
+ main ()
+ {
+
+- return GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+- && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
++ if (GMP_NUMB_BITS == sizeof(mp_limb_t) * CHAR_BIT)
++ return 0;
++ fprintf (stderr, "GMP_NUMB_BITS = %ld\n", (long) GMP_NUMB_BITS);
++ fprintf (stderr, "sizeof(mp_limb_t) = %ld\n", (long) sizeof(mp_limb_t));
++ fprintf (stderr, "sizeof(mp_limb_t) * CHAR_BIT = %ld != GMP_NUMB_BITS\n",
++ (long) (sizeof(mp_limb_t) * CHAR_BIT));
++ return 1;
+
+ ;
+ return 0;
+@@ -14577,14 +14581,14 @@
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+- as_fn_error $? "GMP_NUMB_BITS is incorrect.
+-You probably need to change some of the GMP or MPFR compile options." "$LINENO" 5
++ as_fn_error $? "GMP_NUMB_BITS and sizeof(mp_limb_t) are not consistent.
++You probably need to change some of the GMP or MPFR compile options.
++See 'config.log' for details (search for GMP_NUMB_BITS)." "$LINENO" 5
+ fi
+ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+-fi
+
+
+ if test "$dont_link_with_gmp" = yes ; then
+diff -Naurd mpfr-3.1.2-a/configure.ac mpfr-3.1.2-b/configure.ac
+--- mpfr-3.1.2-a/configure.ac 2013-03-13 15:37:46.000000000 +0000
++++ mpfr-3.1.2-b/configure.ac 2013-03-13 15:37:46.000000000 +0000
+@@ -435,23 +435,29 @@
+ ])
+ fi
+
+-dnl Check for valid GMP_NUMB_BITS and BYTES_PER_MP_LIMB
++dnl Check for GMP_NUMB_BITS and sizeof(mp_limb_t) consistency.
++dnl Problems may occur if gmp.h was generated with some ABI
++dnl and is used with another ABI (or if nails are used).
+ dnl This test doesn't need to link with libgmp (at least it shouldn't).
+-if test "$use_gmp_build" = yes ; then
+- AC_MSG_CHECKING(for valid GMP_NUMB_BITS)
+- AC_RUN_IFELSE([AC_LANG_PROGRAM([[
++AC_MSG_CHECKING(for GMP_NUMB_BITS and sizeof(mp_limb_t) consistency)
++AC_RUN_IFELSE([AC_LANG_PROGRAM([[
++#include <stdio.h>
+ #include <limits.h>
+ #include "gmp.h"
+-#include "gmp-impl.h"
+ ]], [[
+- return GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+- && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB ? 0 : 1;
++ if (GMP_NUMB_BITS == sizeof(mp_limb_t) * CHAR_BIT)
++ return 0;
++ fprintf (stderr, "GMP_NUMB_BITS = %ld\n", (long) GMP_NUMB_BITS);
++ fprintf (stderr, "sizeof(mp_limb_t) = %ld\n", (long) sizeof(mp_limb_t));
++ fprintf (stderr, "sizeof(mp_limb_t) * CHAR_BIT = %ld != GMP_NUMB_BITS\n",
++ (long) (sizeof(mp_limb_t) * CHAR_BIT));
++ return 1;
+ ]])], [AC_MSG_RESULT(yes)], [
+ AC_MSG_RESULT(no)
+- AC_MSG_ERROR([GMP_NUMB_BITS is incorrect.
+-You probably need to change some of the GMP or MPFR compile options.])],
++ AC_MSG_ERROR([GMP_NUMB_BITS and sizeof(mp_limb_t) are not consistent.
++You probably need to change some of the GMP or MPFR compile options.
++See 'config.log' for details (search for GMP_NUMB_BITS).])],
+ [AC_MSG_RESULT([can't test])])
+-fi
+
+
+ dnl We really need to link using libtool. But it is impossible with the current
+diff -Naurd mpfr-3.1.2-a/src/init2.c mpfr-3.1.2-b/src/init2.c
+--- mpfr-3.1.2-a/src/init2.c 2013-03-13 15:37:32.000000000 +0000
++++ mpfr-3.1.2-b/src/init2.c 2014-04-15 22:21:06.220398489 +0000
+@@ -30,11 +30,11 @@
+
+ /* Check if we can represent the number of limbs
+ * associated to the maximum of mpfr_prec_t*/
+- MPFR_ASSERTN( MP_SIZE_T_MAX >= (MPFR_PREC_MAX/BYTES_PER_MP_LIMB) );
++ MPFR_ASSERTN( MP_SIZE_T_MAX >= (MPFR_PREC_MAX/MPFR_BYTES_PER_MP_LIMB) );
+
+- /* Check for correct GMP_NUMB_BITS and BYTES_PER_MP_LIMB */
+- MPFR_ASSERTN( GMP_NUMB_BITS == BYTES_PER_MP_LIMB * CHAR_BIT
+- && sizeof(mp_limb_t) == BYTES_PER_MP_LIMB );
++ /* Check for correct GMP_NUMB_BITS and MPFR_BYTES_PER_MP_LIMB */
++ MPFR_ASSERTN( GMP_NUMB_BITS == MPFR_BYTES_PER_MP_LIMB * CHAR_BIT
++ && sizeof(mp_limb_t) == MPFR_BYTES_PER_MP_LIMB );
+
+ MPFR_ASSERTN (mp_bits_per_limb == GMP_NUMB_BITS);
+
+diff -Naurd mpfr-3.1.2-a/src/mpfr-gmp.h mpfr-3.1.2-b/src/mpfr-gmp.h
+--- mpfr-3.1.2-a/src/mpfr-gmp.h 2013-03-13 15:37:32.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr-gmp.h 2014-04-15 22:21:06.220398489 +0000
+@@ -72,7 +72,6 @@
+ #endif
+
+ /* Define some macros */
+-#define BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
+
+ #define MP_LIMB_T_MAX (~(mp_limb_t)0)
+
+@@ -96,19 +95,19 @@
+ #define SHRT_HIGHBIT SHRT_MIN
+
+ /* MP_LIMB macros */
+-#define MPN_ZERO(dst, n) memset((dst), 0, (n)*BYTES_PER_MP_LIMB)
+-#define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
+-#define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*BYTES_PER_MP_LIMB)
++#define MPN_ZERO(dst, n) memset((dst), 0, (n)*MPFR_BYTES_PER_MP_LIMB)
++#define MPN_COPY_DECR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB)
++#define MPN_COPY_INCR(dst,src,n) memmove((dst),(src),(n)*MPFR_BYTES_PER_MP_LIMB)
+ #define MPN_COPY(dst,src,n) \
+ do \
+ { \
+ if ((dst) != (src)) \
+ { \
+ MPFR_ASSERTD ((char *) (dst) >= (char *) (src) + \
+- (n) * BYTES_PER_MP_LIMB || \
++ (n) * MPFR_BYTES_PER_MP_LIMB || \
+ (char *) (src) >= (char *) (dst) + \
+- (n) * BYTES_PER_MP_LIMB); \
+- memcpy ((dst), (src), (n) * BYTES_PER_MP_LIMB); \
++ (n) * MPFR_BYTES_PER_MP_LIMB); \
++ memcpy ((dst), (src), (n) * MPFR_BYTES_PER_MP_LIMB); \
+ } \
+ } \
+ while (0)
+diff -Naurd mpfr-3.1.2-a/src/mpfr-impl.h mpfr-3.1.2-b/src/mpfr-impl.h
+--- mpfr-3.1.2-a/src/mpfr-impl.h 2013-10-09 13:34:21.000000000 +0000
++++ mpfr-3.1.2-b/src/mpfr-impl.h 2014-04-15 22:21:06.220398489 +0000
+@@ -191,7 +191,7 @@
+ # endif
+ #endif
+
+-
++#define MPFR_BYTES_PER_MP_LIMB (GMP_NUMB_BITS/CHAR_BIT)
+
+ /******************************************************
+ ******************** Check GMP ***********************
+@@ -930,7 +930,7 @@
+ #define MPFR_SET_ALLOC_SIZE(x, n) \
+ ( ((mp_size_t*) MPFR_MANT(x))[-1] = n)
+ #define MPFR_MALLOC_SIZE(s) \
+- ( sizeof(mpfr_size_limb_t) + BYTES_PER_MP_LIMB * ((size_t) s) )
++ ( sizeof(mpfr_size_limb_t) + MPFR_BYTES_PER_MP_LIMB * ((size_t) s) )
+ #define MPFR_SET_MANT_PTR(x,p) \
+ (MPFR_MANT(x) = (mp_limb_t*) ((mpfr_size_limb_t*) p + 1))
+ #define MPFR_GET_REAL_PTR(x) \
+@@ -964,7 +964,7 @@
+ #endif
+
+ #define MPFR_TMP_LIMBS_ALLOC(N) \
+- ((mp_limb_t *) MPFR_TMP_ALLOC ((size_t) (N) * BYTES_PER_MP_LIMB))
++ ((mp_limb_t *) MPFR_TMP_ALLOC ((size_t) (N) * MPFR_BYTES_PER_MP_LIMB))
+
+ /* temporary allocate 1 limb at xp, and initialize mpfr variable x */
+ /* The temporary var doesn't have any size field, but it doesn't matter
+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-04-15 22:20:20.755171478 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2014-04-15 22:21:45.225450147 +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-p7"
++#define MPFR_VERSION_STRING "3.1.2-p8"
+
+ /* 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/mul.c mpfr-3.1.2-b/src/mul.c
+--- mpfr-3.1.2-a/src/mul.c 2013-03-13 15:37:37.000000000 +0000
++++ mpfr-3.1.2-b/src/mul.c 2014-04-15 22:21:06.224398597 +0000
+@@ -106,7 +106,7 @@
+ MPFR_ASSERTD(tn <= k);
+
+ /* Check for no size_t overflow*/
+- MPFR_ASSERTD((size_t) k <= ((size_t) -1) / BYTES_PER_MP_LIMB);
++ MPFR_ASSERTD((size_t) k <= ((size_t) -1) / MPFR_BYTES_PER_MP_LIMB);
+ MPFR_TMP_MARK(marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (k);
+
+@@ -301,7 +301,7 @@
+ MPFR_ASSERTD (tn <= k); /* tn <= k, thus no int overflow */
+
+ /* Check for no size_t overflow*/
+- MPFR_ASSERTD ((size_t) k <= ((size_t) -1) / BYTES_PER_MP_LIMB);
++ MPFR_ASSERTD ((size_t) k <= ((size_t) -1) / MPFR_BYTES_PER_MP_LIMB);
+ MPFR_TMP_MARK (marker);
+ tmp = MPFR_TMP_LIMBS_ALLOC (k);
+
+diff -Naurd mpfr-3.1.2-a/src/stack_interface.c mpfr-3.1.2-b/src/stack_interface.c
+--- mpfr-3.1.2-a/src/stack_interface.c 2013-03-13 15:37:32.000000000 +0000
++++ mpfr-3.1.2-b/src/stack_interface.c 2014-04-15 22:21:06.220398489 +0000
+@@ -26,7 +26,7 @@
+ size_t
+ mpfr_custom_get_size (mpfr_prec_t prec)
+ {
+- return MPFR_PREC2LIMBS (prec) * BYTES_PER_MP_LIMB;
++ return MPFR_PREC2LIMBS (prec) * MPFR_BYTES_PER_MP_LIMB;
+ }
+
+ #undef mpfr_custom_init
+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-04-15 22:20:20.755171478 +0000
++++ mpfr-3.1.2-b/src/version.c 2014-04-15 22:21:45.225450147 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p7";
++ return "3.1.2-p8";
+ }
diff --git a/patches/mpfr/3.1.2/190-div-overflow.patch b/patches/mpfr/3.1.2/190-div-overflow.patch
new file mode 100644
index 0000000..6ff7c4a
--- /dev/null
+++ b/patches/mpfr/3.1.2/190-div-overflow.patch
@@ -0,0 +1,166 @@
+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;
diff --git a/patches/mpfr/3.1.2/200-vasprintf.patch b/patches/mpfr/3.1.2/200-vasprintf.patch
new file mode 100644
index 0000000..43848f7
--- /dev/null
+++ b/patches/mpfr/3.1.2/200-vasprintf.patch
@@ -0,0 +1,138 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2014-06-30 15:17:53.337268149 +0000
++++ mpfr-3.1.2-b/PATCHES 2014-06-30 15:17:53.417270314 +0000
+@@ -0,0 +1 @@
++vasprintf
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2014-06-30 15:17:53.337268149 +0000
++++ mpfr-3.1.2-b/VERSION 2014-06-30 15:17:53.413270206 +0000
+@@ -1 +1 @@
+-3.1.2-p9
++3.1.2-p10
+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:17:53.337268149 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2014-06-30 15:17:53.413270206 +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-p9"
++#define MPFR_VERSION_STRING "3.1.2-p10"
+
+ /* 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/vasprintf.c mpfr-3.1.2-b/src/vasprintf.c
+--- mpfr-3.1.2-a/src/vasprintf.c 2013-11-15 00:51:49.267334408 +0000
++++ mpfr-3.1.2-b/src/vasprintf.c 2014-06-30 15:17:53.377269231 +0000
+@@ -884,14 +884,18 @@
+ first digit, we want the exponent for radix two and the decimal
+ point AFTER the first digit. */
+ {
+- MPFR_ASSERTN (exp > MPFR_EMIN_MIN /4); /* possible overflow */
++ /* An integer overflow is normally not possible since MPFR_EXP_MIN
++ is twice as large as MPFR_EMIN_MIN. */
++ MPFR_ASSERTN (exp > (MPFR_EXP_MIN + 3) / 4);
+ exp = (exp - 1) * 4;
+ }
+ else
+ /* EXP is the exponent for decimal point BEFORE the first digit, we
+ want the exponent for decimal point AFTER the first digit. */
+ {
+- MPFR_ASSERTN (exp > MPFR_EMIN_MIN); /* possible overflow */
++ /* An integer overflow is normally not possible since MPFR_EXP_MIN
++ is twice as large as MPFR_EMIN_MIN. */
++ MPFR_ASSERTN (exp > MPFR_EXP_MIN);
+ --exp;
+ }
+ }
+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:17:53.337268149 +0000
++++ mpfr-3.1.2-b/src/version.c 2014-06-30 15:17:53.413270206 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p9";
++ return "3.1.2-p10";
+ }
+diff -Naurd mpfr-3.1.2-a/tests/tsprintf.c mpfr-3.1.2-b/tests/tsprintf.c
+--- mpfr-3.1.2-a/tests/tsprintf.c 2013-11-15 00:51:49.267334408 +0000
++++ mpfr-3.1.2-b/tests/tsprintf.c 2014-06-30 15:17:53.377269231 +0000
+@@ -1184,6 +1184,69 @@
+ check_emax_aux (MPFR_EMAX_MAX);
+ }
+
++static void
++check_emin_aux (mpfr_exp_t e)
++{
++ mpfr_t x;
++ char *s1, s2[256];
++ int i;
++ mpfr_exp_t emin;
++ mpz_t ee;
++
++ MPFR_ASSERTN (e >= LONG_MIN);
++ emin = mpfr_get_emin ();
++ set_emin (e);
++
++ mpfr_init2 (x, 16);
++ mpz_init (ee);
++
++ mpfr_setmin (x, e);
++ mpz_set_si (ee, e);
++ mpz_sub_ui (ee, ee, 1);
++
++ i = mpfr_asprintf (&s1, "%Ra", x);
++ MPFR_ASSERTN (i > 0);
++
++ gmp_snprintf (s2, 256, "0x1p%Zd", ee);
++
++ if (strcmp (s1, s2) != 0)
++ {
++ printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
++ printf ("Expected %s\n", s2);
++ printf ("Got %s\n", s1);
++ exit (1);
++ }
++
++ mpfr_free_str (s1);
++
++ i = mpfr_asprintf (&s1, "%Rb", x);
++ MPFR_ASSERTN (i > 0);
++
++ gmp_snprintf (s2, 256, "1p%Zd", ee);
++
++ if (strcmp (s1, s2) != 0)
++ {
++ printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
++ printf ("Expected %s\n", s2);
++ printf ("Got %s\n", s1);
++ exit (1);
++ }
++
++ mpfr_free_str (s1);
++
++ mpfr_clear (x);
++ mpz_clear (ee);
++ set_emin (emin);
++}
++
++static void
++check_emin (void)
++{
++ check_emin_aux (-15);
++ check_emin_aux (mpfr_get_emin ());
++ check_emin_aux (MPFR_EMIN_MIN);
++}
++
+ int
+ main (int argc, char **argv)
+ {
+@@ -1203,6 +1266,7 @@
+ decimal ();
+ mixed ();
+ check_emax ();
++ check_emin ();
+
+ #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ locale_da_DK ();
diff --git a/patches/mpfr/3.1.2/210-strtofr.patch b/patches/mpfr/3.1.2/210-strtofr.patch
new file mode 100644
index 0000000..462162e
--- /dev/null
+++ b/patches/mpfr/3.1.2/210-strtofr.patch
@@ -0,0 +1,49 @@
+diff -Naurd mpfr-3.1.2-a/PATCHES mpfr-3.1.2-b/PATCHES
+--- mpfr-3.1.2-a/PATCHES 2014-12-04 01:41:57.131789485 +0000
++++ mpfr-3.1.2-b/PATCHES 2014-12-04 01:41:57.339791833 +0000
+@@ -0,0 +1 @@
++strtofr
+diff -Naurd mpfr-3.1.2-a/VERSION mpfr-3.1.2-b/VERSION
+--- mpfr-3.1.2-a/VERSION 2014-12-04 01:41:57.127789443 +0000
++++ mpfr-3.1.2-b/VERSION 2014-12-04 01:41:57.339791833 +0000
+@@ -1 +1 @@
+-3.1.2-p10
++3.1.2-p11
+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-12-04 01:41:57.127789443 +0000
++++ mpfr-3.1.2-b/src/mpfr.h 2014-12-04 01:41:57.335791790 +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-p10"
++#define MPFR_VERSION_STRING "3.1.2-p11"
+
+ /* 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/strtofr.c mpfr-3.1.2-b/src/strtofr.c
+--- mpfr-3.1.2-a/src/strtofr.c 2013-03-13 15:37:32.000000000 +0000
++++ mpfr-3.1.2-b/src/strtofr.c 2014-12-04 01:41:57.287791246 +0000
+@@ -473,8 +473,10 @@
+ /* prec bits corresponds to ysize limbs */
+ ysize_bits = ysize * GMP_NUMB_BITS;
+ /* and to ysize_bits >= prec > MPFR_PREC (x) bits */
+- y = MPFR_TMP_LIMBS_ALLOC (2 * ysize + 1);
+- y += ysize; /* y has (ysize+1) allocated limbs */
++ /* we need to allocate one more limb to work around bug
++ https://gmplib.org/list-archives/gmp-bugs/2013-December/003267.html */
++ y = MPFR_TMP_LIMBS_ALLOC (2 * ysize + 2);
++ y += ysize; /* y has (ysize+2) allocated limbs */
+
+ /* pstr_size is the number of characters we read in pstr->mant
+ to have at least ysize full limbs.
+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-12-04 01:41:57.131789485 +0000
++++ mpfr-3.1.2-b/src/version.c 2014-12-04 01:41:57.339791833 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.2-p10";
++ return "3.1.2-p11";
+ }
diff --git a/patches/mpfr/3.1.3/110-lngamma-and-doc.patch b/patches/mpfr/3.1.3/110-lngamma-and-doc.patch
new file mode 100644
index 0000000..d7e1cbf
--- /dev/null
+++ b/patches/mpfr/3.1.3/110-lngamma-and-doc.patch
@@ -0,0 +1,1117 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2015-07-02 10:49:23.950112879 +0000
++++ mpfr-3.1.3-b/PATCHES 2015-07-02 10:49:24.042113845 +0000
+@@ -0,0 +1 @@
++lngamma-and-doc
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/VERSION 2015-07-02 10:49:24.042113845 +0000
+@@ -1 +1 @@
+-3.1.3
++3.1.3-p1
+diff -Naurd mpfr-3.1.3-a/doc/mpfr.texi mpfr-3.1.3-b/doc/mpfr.texi
+--- mpfr-3.1.3-a/doc/mpfr.texi 2015-06-19 19:55:11.000000000 +0000
++++ mpfr-3.1.3-b/doc/mpfr.texi 2015-07-02 10:49:24.018113593 +0000
+@@ -810,13 +810,17 @@
+ When the input point is in the closure of the domain of the mathematical
+ function and an input argument is +0 (resp.@: @minus{}0), one considers
+ the limit when the corresponding argument approaches 0 from above
+-(resp.@: below). If the limit is not defined (e.g., @code{mpfr_log} on
+-@minus{}0), the behavior is specified in the description of the MPFR function.
++(resp.@: below), if possible. If the limit is not defined (e.g.,
++@code{mpfr_sqrt} and @code{mpfr_log} on @minus{}0), the behavior is
++specified in the description of the MPFR function, but must be consistent
++with the rule from the above paragraph (e.g., @code{mpfr_log} on @pom{}0
++gives @minus{}Inf).
+
+ When the result is equal to 0, its sign is determined by considering the
+ limit as if the input point were not in the domain: If one approaches 0
+ from above (resp.@: below), the result is +0 (resp.@: @minus{}0);
+-for example, @code{mpfr_sin} on +0 gives +0.
++for example, @code{mpfr_sin} on @minus{}0 gives @minus{}0 and
++@code{mpfr_acos} on 1 gives +0 (in all rounding modes).
+ In the other cases, the sign is specified in the description of the MPFR
+ function; for example @code{mpfr_max} on @minus{}0 and +0 gives +0.
+
+@@ -832,8 +836,8 @@
+ @c that advantages in practice), like for any bug fix.
+ Example: @code{mpfr_hypot} on (NaN,0) gives NaN, but @code{mpfr_hypot}
+ on (NaN,+Inf) gives +Inf (as specified in @ref{Special Functions}),
+-since for any finite input @var{x}, @code{mpfr_hypot} on (@var{x},+Inf)
+-gives +Inf.
++since for any finite or infinite input @var{x}, @code{mpfr_hypot} on
++(@var{x},+Inf) gives +Inf.
+
+ @node Exceptions, Memory Handling, Floating-Point Values on Special Numbers, MPFR Basics
+ @comment node-name, next, previous, up
+@@ -1581,7 +1585,8 @@
+ @deftypefunx int mpfr_add_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+ @deftypefunx int mpfr_add_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @math{@var{op1} + @var{op2}} rounded in the direction
+-@var{rnd}. For types having no signed zero, it is considered unsigned
++@var{rnd}. The IEEE-754 rules are used, in particular for signed zeros.
++But for types having no signed zeros, 0 is considered unsigned
+ (i.e., (+0) + 0 = (+0) and (@minus{}0) + 0 = (@minus{}0)).
+ The @code{mpfr_add_d} function assumes that the radix of the @code{double} type
+ is a power of 2, with a precision at most that declared by the C implementation
+@@ -1599,7 +1604,8 @@
+ @deftypefunx int mpfr_sub_z (mpfr_t @var{rop}, mpfr_t @var{op1}, mpz_t @var{op2}, mpfr_rnd_t @var{rnd})
+ @deftypefunx int mpfr_sub_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @math{@var{op1} - @var{op2}} rounded in the direction
+-@var{rnd}. For types having no signed zero, it is considered unsigned
++@var{rnd}. The IEEE-754 rules are used, in particular for signed zeros.
++But for types having no signed zeros, 0 is considered unsigned
+ (i.e., (+0) @minus{} 0 = (+0), (@minus{}0) @minus{} 0 = (@minus{}0),
+ 0 @minus{} (+0) = (@minus{}0) and 0 @minus{} (@minus{}0) = (+0)).
+ The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_d_sub}
+@@ -1615,7 +1621,7 @@
+ Set @var{rop} to @math{@var{op1} @GMPtimes{} @var{op2}} rounded in the
+ direction @var{rnd}.
+ When a result is zero, its sign is the product of the signs of the operands
+-(for types having no signed zero, it is considered positive).
++(for types having no signed zeros, 0 is considered positive).
+ The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_mul_d}.
+ @end deftypefun
+
+@@ -1635,7 +1641,7 @@
+ @deftypefunx int mpfr_div_q (mpfr_t @var{rop}, mpfr_t @var{op1}, mpq_t @var{op2}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @math{@var{op1}/@var{op2}} rounded in the direction @var{rnd}.
+ When a result is zero, its sign is the product of the signs of the operands
+-(for types having no signed zero, it is considered positive).
++(for types having no signed zeros, 0 is considered positive).
+ The same restrictions than for @code{mpfr_add_d} apply to @code{mpfr_d_div}
+ and @code{mpfr_div_d}.
+ @end deftypefun
+@@ -1643,15 +1649,18 @@
+ @deftypefun int mpfr_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+ @deftypefunx int mpfr_sqrt_ui (mpfr_t @var{rop}, unsigned long int @var{op}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @m{\sqrt{@var{op}}, the square root of @var{op}}
+-rounded in the direction @var{rnd} (set @var{rop} to @minus{}0 if @var{op} is
+-@minus{}0, to be consistent with the IEEE 754 standard).
++rounded in the direction @var{rnd}. Set @var{rop} to @minus{}0 if
++@var{op} is @minus{}0, to be consistent with the IEEE 754 standard.
+ Set @var{rop} to NaN if @var{op} is negative.
+ @end deftypefun
+
+ @deftypefun int mpfr_rec_sqrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @m{1/\sqrt{@var{op}}, the reciprocal square root of @var{op}}
+-rounded in the direction @var{rnd}. Set @var{rop} to +Inf if @var{op} is
+-@pom{}0, +0 if @var{op} is +Inf, and NaN if @var{op} is negative.
++rounded in the direction @var{rnd}. Set @var{rop} to +Inf if @var{op} is
++@pom{}0, +0 if @var{op} is +Inf, and NaN if @var{op} is negative. Warning!
++Therefore the result on @minus{}0 is different from the one of the rSqrt
++function recommended by the IEEE 754-2008 standard (Section 9.2.1), which
++is @minus{}Inf instead of +Inf.
+ @end deftypefun
+
+ @deftypefun int mpfr_cbrt (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@@ -1832,7 +1841,9 @@
+ @m{\log_2 @var{op}, log2(@var{op})} or
+ @m{\log_{10} @var{op}, log10(@var{op})}, respectively,
+ rounded in the direction @var{rnd}.
+-Set @var{rop} to @minus{}Inf if @var{op} is @minus{}0
++Set @var{rop} to +0 if @var{op} is 1 (in all rounding modes),
++for consistency with the ISO C99 and IEEE 754-2008 standards.
++Set @var{rop} to @minus{}Inf if @var{op} is @pom{}0
+ (i.e., the sign of the zero has no influence on the result).
+ @end deftypefun
+
+@@ -2003,8 +2014,11 @@
+ @deftypefun int mpfr_lngamma (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to the value of the logarithm of the Gamma function on @var{op},
+ rounded in the direction @var{rnd}.
+-When @math{@minus{}2@var{k}@minus{}1 @le{} @var{op} @le{} @minus{}2@var{k}},
+-@var{k} being a non-negative integer, @var{rop} is set to NaN.
++When @var{op} is 1 or 2, set @var{rop} to +0 (in all rounding modes).
++When @var{op} is an infinity or a nonpositive integer, set @var{rop} to +Inf,
++following the general rules on special values.
++When @math{@minus{}2@var{k}@minus{}1 < @var{op} < @minus{}2@var{k}},
++@var{k} being a nonnegative integer, set @var{rop} to NaN@.
+ See also @code{mpfr_lgamma}.
+ @end deftypefun
+
+@@ -2012,10 +2026,11 @@
+ Set @var{rop} to the value of the logarithm of the absolute value of the
+ Gamma function on @var{op}, rounded in the direction @var{rnd}. The sign
+ (1 or @minus{}1) of Gamma(@var{op}) is returned in the object pointed to
+-by @var{signp}. When @var{op} is an infinity or a non-positive integer, set
+-@var{rop} to +Inf. When @var{op} is NaN, @minus{}Inf or a negative integer,
+-*@var{signp} is undefined, and when @var{op} is @pom{}0, *@var{signp} is
+-the sign of the zero.
++by @var{signp}.
++When @var{op} is 1 or 2, set @var{rop} to +0 (in all rounding modes).
++When @var{op} is an infinity or a nonpositive integer, set @var{rop} to +Inf.
++When @var{op} is NaN, @minus{}Inf or a negative integer, *@var{signp} is
++undefined, and when @var{op} is @pom{}0, *@var{signp} is the sign of the zero.
+ @end deftypefun
+
+ @deftypefun int mpfr_digamma (mpfr_t @var{rop}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
+@@ -2064,7 +2079,10 @@
+ @deftypefunx int mpfr_fms (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_t @var{op3}, mpfr_rnd_t @var{rnd})
+ Set @var{rop} to @math{(@var{op1} @GMPtimes{} @var{op2}) + @var{op3}}
+ (resp.@: @math{(@var{op1} @GMPtimes{} @var{op2}) - @var{op3}})
+-rounded in the direction @var{rnd}.
++rounded in the direction @var{rnd}. Concerning special values (signed zeros,
++infinities, NaN), these functions behave like a multiplication followed by a
++separate addition or subtraction. That is, the fused operation matters only
++for rounding.
+ @end deftypefun
+
+ @deftypefun int mpfr_agm (mpfr_t @var{rop}, mpfr_t @var{op1}, mpfr_t @var{op2}, mpfr_rnd_t @var{rnd})
+@@ -2089,8 +2107,8 @@
+ i.e., $\sqrt{x^2+y^2}$,
+ @end tex
+ rounded in the direction @var{rnd}.
+-Special values are handled as described in Section F.9.4.3 of
+-the ISO C99 and IEEE 754-2008 standards:
++Special values are handled as described in the ISO C99 (Section F.9.4.3)
++and IEEE 754-2008 (Section 9.2.1) standards:
+ If @var{x} or @var{y} is an infinity, then +Inf is returned in @var{rop},
+ even if the other number is NaN.
+ @end deftypefun
+diff -Naurd mpfr-3.1.3-a/doc/mpfr.info mpfr-3.1.3-b/doc/mpfr.info
+--- mpfr-3.1.3-a/doc/mpfr.info 2015-06-19 19:55:53.000000000 +0000
++++ mpfr-3.1.3-b/doc/mpfr.info 2015-07-02 10:49:38.718267817 +0000
+@@ -1,4 +1,4 @@
+-This is mpfr.info, produced by makeinfo version 5.2 from mpfr.texi.
++This is mpfr.info, produced by makeinfo version 6.0 from mpfr.texi.
+
+ This manual documents how to install and use the Multiple Precision
+ Floating-Point Reliable Library, version 3.1.3.
+@@ -55,7 +55,7 @@
+ MPFR Copying Conditions
+ ***********************
+
+-The GNU MPFR library (or MPFR for short) is "free"; this means that
++The GNU MPFR library (or MPFR for short) is “free”; this means that
+ everyone is free to use it and free to redistribute it on a free basis.
+ The library is not in the public domain; it is copyrighted and there are
+ restrictions on its distribution, but these restrictions are designed to
+@@ -418,7 +418,7 @@
+ 4.2 Nomenclature and Types
+ ==========================
+
+-A "floating-point number", or "float" for short, is an arbitrary
++A “floating-point number”, or “float” for short, is an arbitrary
+ precision significand (also called mantissa) with a limited precision
+ exponent. The C data type for such objects is ‘mpfr_t’ (internally
+ defined as a one-element array of a structure, and ‘mpfr_ptr’ is the C
+@@ -432,7 +432,7 @@
+ to the other functions supported by MPFR. Unless documented otherwise,
+ the sign bit of a NaN is unspecified.
+
+-The "precision" is the number of bits used to represent the significand
++The “precision” is the number of bits used to represent the significand
+ of a floating-point number; the corresponding C data type is
+ ‘mpfr_prec_t’. The precision can be any integer between ‘MPFR_PREC_MIN’
+ and ‘MPFR_PREC_MAX’. In the current implementation, ‘MPFR_PREC_MIN’ is
+@@ -446,7 +446,7 @@
+ may abort, crash or have undefined behavior (depending on your C
+ implementation).
+
+-The "rounding mode" specifies the way to round the result of a
++The “rounding mode” specifies the way to round the result of a
+ floating-point operation, in case the exact result can not be
+ represented exactly in the destination significand; the corresponding C
+ data type is ‘mpfr_rnd_t’.
+@@ -499,14 +499,14 @@
+ representable numbers, it is rounded to the one with the least
+ significant bit set to zero. For example, the number 2.5, which is
+ represented by (10.1) in binary, is rounded to (10.0)=2 with a precision
+-of two bits, and not to (11.0)=3. This rule avoids the "drift"
++of two bits, and not to (11.0)=3. This rule avoids the “drift”
+ phenomenon mentioned by Knuth in volume 2 of The Art of Computer
+ Programming (Section 4.2.2).
+
+ Most MPFR functions take as first argument the destination variable,
+ as second and following arguments the input variables, as last argument
+ a rounding mode, and have a return value of type ‘int’, called the
+-"ternary value". The value stored in the destination variable is
++“ternary value”. The value stored in the destination variable is
+ correctly rounded, i.e., MPFR behaves as if it computed the result with
+ an infinite precision, then rounded it to the precision of this
+ variable. The input variables are regarded as exact (in particular,
+@@ -572,15 +572,18 @@
+ When the input point is in the closure of the domain of the
+ mathematical function and an input argument is +0 (resp. −0), one
+ considers the limit when the corresponding argument approaches 0 from
+-above (resp. below). If the limit is not defined (e.g., ‘mpfr_log’ on
+-−0), the behavior is specified in the description of the MPFR function.
++above (resp. below), if possible. If the limit is not defined (e.g.,
++‘mpfr_sqrt’ and ‘mpfr_log’ on −0), the behavior is specified in the
++description of the MPFR function, but must be consistent with the rule
++from the above paragraph (e.g., ‘mpfr_log’ on ±0 gives −Inf).
+
+ When the result is equal to 0, its sign is determined by considering
+ the limit as if the input point were not in the domain: If one
+ approaches 0 from above (resp. below), the result is +0 (resp. −0); for
+-example, ‘mpfr_sin’ on +0 gives +0. In the other cases, the sign is
+-specified in the description of the MPFR function; for example
+-‘mpfr_max’ on −0 and +0 gives +0.
++example, ‘mpfr_sin’ on −0 gives −0 and ‘mpfr_acos’ on 1 gives +0 (in all
++rounding modes). In the other cases, the sign is specified in the
++description of the MPFR function; for example ‘mpfr_max’ on −0 and +0
++gives +0.
+
+ When the input point is not in the closure of the domain of the
+ function, the result is NaN. Example: ‘mpfr_sqrt’ on −17 gives NaN.
+@@ -590,8 +593,8 @@
+ numbers; such a case is always explicitly specified in *note MPFR
+ Interface::. Example: ‘mpfr_hypot’ on (NaN,0) gives NaN, but
+ ‘mpfr_hypot’ on (NaN,+Inf) gives +Inf (as specified in *note Special
+-Functions::), since for any finite input X, ‘mpfr_hypot’ on (X,+Inf)
+-gives +Inf.
++Functions::), since for any finite or infinite input X, ‘mpfr_hypot’ on
++(X,+Inf) gives +Inf.
+
+ 
+ File: mpfr.info, Node: Exceptions, Next: Memory Handling, Prev: Floating-Point Values on Special Numbers, Up: MPFR Basics
+@@ -1253,8 +1256,9 @@
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_add_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+- Set ROP to OP1 + OP2 rounded in the direction RND. For types
+- having no signed zero, it is considered unsigned (i.e., (+0) + 0 =
++ Set ROP to OP1 + OP2 rounded in the direction RND. The IEEE-754
++ rules are used, in particular for signed zeros. But for types
++ having no signed zeros, 0 is considered unsigned (i.e., (+0) + 0 =
+ (+0) and (−0) + 0 = (−0)). The ‘mpfr_add_d’ function assumes that
+ the radix of the ‘double’ type is a power of 2, with a precision at
+ most that declared by the C implementation (macro
+@@ -1280,8 +1284,9 @@
+ mpfr_rnd_t RND)
+ -- Function: int mpfr_sub_q (mpfr_t ROP, mpfr_t OP1, mpq_t OP2,
+ mpfr_rnd_t RND)
+- Set ROP to OP1 - OP2 rounded in the direction RND. For types
+- having no signed zero, it is considered unsigned (i.e., (+0) − 0 =
++ Set ROP to OP1 - OP2 rounded in the direction RND. The IEEE-754
++ rules are used, in particular for signed zeros. But for types
++ having no signed zeros, 0 is considered unsigned (i.e., (+0) − 0 =
+ (+0), (−0) − 0 = (−0), 0 − (+0) = (−0) and 0 − (−0) = (+0)). The
+ same restrictions than for ‘mpfr_add_d’ apply to ‘mpfr_d_sub’ and
+ ‘mpfr_sub_d’.
+@@ -1300,7 +1305,7 @@
+ mpfr_rnd_t RND)
+ Set ROP to OP1 times OP2 rounded in the direction RND. When a
+ result is zero, its sign is the product of the signs of the
+- operands (for types having no signed zero, it is considered
++ operands (for types having no signed zeros, 0 is considered
+ positive). The same restrictions than for ‘mpfr_add_d’ apply to
+ ‘mpfr_mul_d’.
+
+@@ -1327,21 +1332,24 @@
+ mpfr_rnd_t RND)
+ Set ROP to OP1/OP2 rounded in the direction RND. When a result is
+ zero, its sign is the product of the signs of the operands (for
+- types having no signed zero, it is considered positive). The same
++ types having no signed zeros, 0 is considered positive). The same
+ restrictions than for ‘mpfr_add_d’ apply to ‘mpfr_d_div’ and
+ ‘mpfr_div_d’.
+
+ -- Function: int mpfr_sqrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_sqrt_ui (mpfr_t ROP, unsigned long int OP,
+ mpfr_rnd_t RND)
+- Set ROP to the square root of OP rounded in the direction RND (set
+- ROP to −0 if OP is −0, to be consistent with the IEEE 754
+- standard). Set ROP to NaN if OP is negative.
++ Set ROP to the square root of OP rounded in the direction RND. Set
++ ROP to −0 if OP is −0, to be consistent with the IEEE 754 standard.
++ Set ROP to NaN if OP is negative.
+
+ -- Function: int mpfr_rec_sqrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the reciprocal square root of OP rounded in the
+ direction RND. Set ROP to +Inf if OP is ±0, +0 if OP is +Inf, and
+- NaN if OP is negative.
++ NaN if OP is negative. Warning! Therefore the result on −0 is
++ different from the one of the rSqrt function recommended by the
++ IEEE 754-2008 standard (Section 9.2.1), which is −Inf instead of
++ +Inf.
+
+ -- Function: int mpfr_cbrt (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_root (mpfr_t ROP, mpfr_t OP, unsigned long int K,
+@@ -1515,8 +1523,10 @@
+ -- Function: int mpfr_log2 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_log10 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the natural logarithm of OP, log2(OP) or log10(OP),
+- respectively, rounded in the direction RND. Set ROP to −Inf if OP
+- is −0 (i.e., the sign of the zero has no influence on the result).
++ respectively, rounded in the direction RND. Set ROP to +0 if OP is
++ 1 (in all rounding modes), for consistency with the ISO C99 and
++ IEEE 754-2008 standards. Set ROP to −Inf if OP is ±0 (i.e., the
++ sign of the zero has no influence on the result).
+
+ -- Function: int mpfr_exp (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ -- Function: int mpfr_exp2 (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+@@ -1649,17 +1659,21 @@
+
+ -- Function: int mpfr_lngamma (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the logarithm of the Gamma function on OP,
+- rounded in the direction RND. When −2K−1 <= OP <= −2K, K being a
+- non-negative integer, ROP is set to NaN. See also ‘mpfr_lgamma’.
++ rounded in the direction RND. When OP is 1 or 2, set ROP to +0 (in
++ all rounding modes). When OP is an infinity or a nonpositive
++ integer, set ROP to +Inf, following the general rules on special
++ values. When −2K−1 < OP < −2K, K being a nonnegative integer, set
++ ROP to NaN. See also ‘mpfr_lgamma’.
+
+ -- Function: int mpfr_lgamma (mpfr_t ROP, int *SIGNP, mpfr_t OP,
+ mpfr_rnd_t RND)
+ Set ROP to the value of the logarithm of the absolute value of the
+ Gamma function on OP, rounded in the direction RND. The sign (1 or
+ −1) of Gamma(OP) is returned in the object pointed to by SIGNP.
+- When OP is an infinity or a non-positive integer, set ROP to +Inf.
+- When OP is NaN, −Inf or a negative integer, *SIGNP is undefined,
+- and when OP is ±0, *SIGNP is the sign of the zero.
++ When OP is 1 or 2, set ROP to +0 (in all rounding modes). When OP
++ is an infinity or a nonpositive integer, set ROP to +Inf. When OP
++ is NaN, −Inf or a negative integer, *SIGNP is undefined, and when
++ OP is ±0, *SIGNP is the sign of the zero.
+
+ -- Function: int mpfr_digamma (mpfr_t ROP, mpfr_t OP, mpfr_rnd_t RND)
+ Set ROP to the value of the Digamma (sometimes also called Psi)
+@@ -1703,7 +1717,10 @@
+ -- Function: int mpfr_fms (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2, mpfr_t
+ OP3, mpfr_rnd_t RND)
+ Set ROP to (OP1 times OP2) + OP3 (resp. (OP1 times OP2) - OP3)
+- rounded in the direction RND.
++ rounded in the direction RND. Concerning special values (signed
++ zeros, infinities, NaN), these functions behave like a
++ multiplication followed by a separate addition or subtraction.
++ That is, the fused operation matters only for rounding.
+
+ -- Function: int mpfr_agm (mpfr_t ROP, mpfr_t OP1, mpfr_t OP2,
+ mpfr_rnd_t RND)
+@@ -1717,9 +1734,10 @@
+ RND)
+ Set ROP to the Euclidean norm of X and Y, i.e., the square root of
+ the sum of the squares of X and Y, rounded in the direction RND.
+- Special values are handled as described in Section F.9.4.3 of the
+- ISO C99 and IEEE 754-2008 standards: If X or Y is an infinity, then
+- +Inf is returned in ROP, even if the other number is NaN.
++ Special values are handled as described in the ISO C99 (Section
++ F.9.4.3) and IEEE 754-2008 (Section 9.2.1) standards: If X or Y is
++ an infinity, then +Inf is returned in ROP, even if the other number
++ is NaN.
+
+ -- Function: int mpfr_ai (mpfr_t ROP, mpfr_t X, mpfr_rnd_t RND)
+ Set ROP to the value of the Airy function Ai on X, rounded in the
+@@ -2670,7 +2688,7 @@
+ 5.16 Internals
+ ==============
+
+-A "limb" means the part of a multi-precision number that fits in a
++A “limb” means the part of a multi-precision number that fits in a
+ single word. Usually a limb contains 32 or 64 bits. The C data type
+ for a limb is ‘mp_limb_t’.
+
+@@ -3140,7 +3158,7 @@
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+- functional and useful document "free" in the sense of freedom: to
++ functional and useful document “free” in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+@@ -3655,9 +3673,9 @@
+ * Menu:
+
+ * mpfr_abs: Basic Arithmetic Functions.
+- (line 160)
+-* mpfr_acos: Special Functions. (line 51)
+-* mpfr_acosh: Special Functions. (line 115)
++ (line 165)
++* mpfr_acos: Special Functions. (line 53)
++* mpfr_acosh: Special Functions. (line 117)
+ * mpfr_add: Basic Arithmetic Functions.
+ (line 6)
+ * mpfr_add_d: Basic Arithmetic Functions.
+@@ -3670,15 +3688,15 @@
+ (line 8)
+ * mpfr_add_z: Basic Arithmetic Functions.
+ (line 14)
+-* mpfr_agm: Special Functions. (line 210)
+-* mpfr_ai: Special Functions. (line 226)
+-* mpfr_asin: Special Functions. (line 52)
+-* mpfr_asinh: Special Functions. (line 116)
++* mpfr_agm: Special Functions. (line 219)
++* mpfr_ai: Special Functions. (line 236)
++* mpfr_asin: Special Functions. (line 54)
++* mpfr_asinh: Special Functions. (line 118)
+ * mpfr_asprintf: Formatted Output Functions.
+ (line 193)
+-* mpfr_atan: Special Functions. (line 53)
+-* mpfr_atan2: Special Functions. (line 63)
+-* mpfr_atanh: Special Functions. (line 117)
++* mpfr_atan: Special Functions. (line 55)
++* mpfr_atan2: Special Functions. (line 65)
++* mpfr_atanh: Special Functions. (line 119)
+ * mpfr_buildopt_decimal_p: Miscellaneous Functions.
+ (line 162)
+ * mpfr_buildopt_gmpinternals_p: Miscellaneous Functions.
+@@ -3690,7 +3708,7 @@
+ * mpfr_can_round: Rounding Related Functions.
+ (line 39)
+ * mpfr_cbrt: Basic Arithmetic Functions.
+- (line 108)
++ (line 113)
+ * mpfr_ceil: Integer Related Functions.
+ (line 7)
+ * mpfr_check_range: Exception Related Functions.
+@@ -3735,18 +3753,18 @@
+ (line 27)
+ * mpfr_cmp_z: Comparison Functions.
+ (line 11)
+-* mpfr_const_catalan: Special Functions. (line 237)
+-* mpfr_const_euler: Special Functions. (line 236)
+-* mpfr_const_log2: Special Functions. (line 234)
+-* mpfr_const_pi: Special Functions. (line 235)
++* mpfr_const_catalan: Special Functions. (line 247)
++* mpfr_const_euler: Special Functions. (line 246)
++* mpfr_const_log2: Special Functions. (line 244)
++* mpfr_const_pi: Special Functions. (line 245)
+ * mpfr_copysign: Miscellaneous Functions.
+ (line 109)
+-* mpfr_cos: Special Functions. (line 29)
+-* mpfr_cosh: Special Functions. (line 95)
+-* mpfr_cot: Special Functions. (line 47)
+-* mpfr_coth: Special Functions. (line 111)
+-* mpfr_csc: Special Functions. (line 46)
+-* mpfr_csch: Special Functions. (line 110)
++* mpfr_cos: Special Functions. (line 31)
++* mpfr_cosh: Special Functions. (line 97)
++* mpfr_cot: Special Functions. (line 49)
++* mpfr_coth: Special Functions. (line 113)
++* mpfr_csc: Special Functions. (line 48)
++* mpfr_csch: Special Functions. (line 112)
+ * mpfr_custom_get_exp: Custom Interface. (line 75)
+ * mpfr_custom_get_kind: Custom Interface. (line 65)
+ * mpfr_custom_get_significand: Custom Interface. (line 70)
+@@ -3756,47 +3774,47 @@
+ * mpfr_custom_move: Custom Interface. (line 82)
+ * MPFR_DECL_INIT: Initialization Functions.
+ (line 74)
+-* mpfr_digamma: Special Functions. (line 166)
++* mpfr_digamma: Special Functions. (line 172)
+ * mpfr_dim: Basic Arithmetic Functions.
+- (line 166)
++ (line 171)
+ * mpfr_div: Basic Arithmetic Functions.
+- (line 72)
++ (line 74)
+ * mpfr_divby0_p: Exception Related Functions.
+ (line 134)
+ * mpfr_div_2exp: Compatibility with MPF.
+ (line 49)
+ * mpfr_div_2si: Basic Arithmetic Functions.
+- (line 181)
++ (line 186)
+ * mpfr_div_2ui: Basic Arithmetic Functions.
+- (line 179)
++ (line 184)
+ * mpfr_div_d: Basic Arithmetic Functions.
+- (line 84)
++ (line 86)
+ * mpfr_div_q: Basic Arithmetic Functions.
+- (line 88)
++ (line 90)
+ * mpfr_div_si: Basic Arithmetic Functions.
+- (line 80)
++ (line 82)
+ * mpfr_div_ui: Basic Arithmetic Functions.
+- (line 76)
++ (line 78)
+ * mpfr_div_z: Basic Arithmetic Functions.
+- (line 86)
++ (line 88)
+ * mpfr_d_div: Basic Arithmetic Functions.
+- (line 82)
++ (line 84)
+ * mpfr_d_sub: Basic Arithmetic Functions.
+- (line 35)
+-* mpfr_eint: Special Functions. (line 133)
++ (line 36)
++* mpfr_eint: Special Functions. (line 135)
+ * mpfr_eq: Compatibility with MPF.
+ (line 28)
+ * mpfr_equal_p: Comparison Functions.
+ (line 59)
+ * mpfr_erangeflag_p: Exception Related Functions.
+ (line 137)
+-* mpfr_erf: Special Functions. (line 177)
+-* mpfr_erfc: Special Functions. (line 178)
+-* mpfr_exp: Special Functions. (line 23)
+-* mpfr_exp10: Special Functions. (line 25)
+-* mpfr_exp2: Special Functions. (line 24)
+-* mpfr_expm1: Special Functions. (line 129)
+-* mpfr_fac_ui: Special Functions. (line 121)
++* mpfr_erf: Special Functions. (line 183)
++* mpfr_erfc: Special Functions. (line 184)
++* mpfr_exp: Special Functions. (line 25)
++* mpfr_exp10: Special Functions. (line 27)
++* mpfr_exp2: Special Functions. (line 26)
++* mpfr_expm1: Special Functions. (line 131)
++* mpfr_fac_ui: Special Functions. (line 123)
+ * mpfr_fits_intmax_p: Conversion Functions.
+ (line 150)
+ * mpfr_fits_sint_p: Conversion Functions.
+@@ -3815,20 +3833,20 @@
+ (line 147)
+ * mpfr_floor: Integer Related Functions.
+ (line 8)
+-* mpfr_fma: Special Functions. (line 203)
++* mpfr_fma: Special Functions. (line 209)
+ * mpfr_fmod: Integer Related Functions.
+ (line 92)
+-* mpfr_fms: Special Functions. (line 205)
++* mpfr_fms: Special Functions. (line 211)
+ * mpfr_fprintf: Formatted Output Functions.
+ (line 157)
+ * mpfr_frac: Integer Related Functions.
+ (line 76)
+-* mpfr_free_cache: Special Functions. (line 244)
++* mpfr_free_cache: Special Functions. (line 254)
+ * mpfr_free_str: Conversion Functions.
+ (line 137)
+ * mpfr_frexp: Conversion Functions.
+ (line 45)
+-* mpfr_gamma: Special Functions. (line 148)
++* mpfr_gamma: Special Functions. (line 150)
+ * mpfr_get_d: Conversion Functions.
+ (line 7)
+ * mpfr_get_decimal64: Conversion Functions.
+@@ -3887,7 +3905,7 @@
+ (line 56)
+ * mpfr_greater_p: Comparison Functions.
+ (line 55)
+-* mpfr_hypot: Special Functions. (line 218)
++* mpfr_hypot: Special Functions. (line 227)
+ * mpfr_inexflag_p: Exception Related Functions.
+ (line 136)
+ * mpfr_inf_p: Comparison Functions.
+@@ -3922,21 +3940,21 @@
+ (line 31)
+ * mpfr_integer_p: Integer Related Functions.
+ (line 119)
+-* mpfr_j0: Special Functions. (line 182)
+-* mpfr_j1: Special Functions. (line 183)
+-* mpfr_jn: Special Functions. (line 184)
++* mpfr_j0: Special Functions. (line 188)
++* mpfr_j1: Special Functions. (line 189)
++* mpfr_jn: Special Functions. (line 190)
+ * mpfr_lessequal_p: Comparison Functions.
+ (line 58)
+ * mpfr_lessgreater_p: Comparison Functions.
+ (line 64)
+ * mpfr_less_p: Comparison Functions.
+ (line 57)
+-* mpfr_lgamma: Special Functions. (line 157)
+-* mpfr_li2: Special Functions. (line 143)
+-* mpfr_lngamma: Special Functions. (line 152)
++* mpfr_lgamma: Special Functions. (line 162)
++* mpfr_li2: Special Functions. (line 145)
++* mpfr_lngamma: Special Functions. (line 154)
+ * mpfr_log: Special Functions. (line 16)
+ * mpfr_log10: Special Functions. (line 18)
+-* mpfr_log1p: Special Functions. (line 125)
++* mpfr_log1p: Special Functions. (line 127)
+ * mpfr_log2: Special Functions. (line 17)
+ * mpfr_max: Miscellaneous Functions.
+ (line 22)
+@@ -3947,29 +3965,29 @@
+ * mpfr_modf: Integer Related Functions.
+ (line 82)
+ * mpfr_mul: Basic Arithmetic Functions.
+- (line 51)
++ (line 53)
+ * mpfr_mul_2exp: Compatibility with MPF.
+ (line 47)
+ * mpfr_mul_2si: Basic Arithmetic Functions.
+- (line 174)
++ (line 179)
+ * mpfr_mul_2ui: Basic Arithmetic Functions.
+- (line 172)
++ (line 177)
+ * mpfr_mul_d: Basic Arithmetic Functions.
+- (line 57)
++ (line 59)
+ * mpfr_mul_q: Basic Arithmetic Functions.
+- (line 61)
++ (line 63)
+ * mpfr_mul_si: Basic Arithmetic Functions.
+- (line 55)
++ (line 57)
+ * mpfr_mul_ui: Basic Arithmetic Functions.
+- (line 53)
++ (line 55)
+ * mpfr_mul_z: Basic Arithmetic Functions.
+- (line 59)
++ (line 61)
+ * mpfr_nanflag_p: Exception Related Functions.
+ (line 135)
+ * mpfr_nan_p: Comparison Functions.
+ (line 39)
+ * mpfr_neg: Basic Arithmetic Functions.
+- (line 159)
++ (line 164)
+ * mpfr_nextabove: Miscellaneous Functions.
+ (line 15)
+ * mpfr_nextbelow: Miscellaneous Functions.
+@@ -3983,13 +4001,13 @@
+ * mpfr_overflow_p: Exception Related Functions.
+ (line 133)
+ * mpfr_pow: Basic Arithmetic Functions.
+- (line 116)
++ (line 121)
+ * mpfr_pow_si: Basic Arithmetic Functions.
+- (line 120)
++ (line 125)
+ * mpfr_pow_ui: Basic Arithmetic Functions.
+- (line 118)
++ (line 123)
+ * mpfr_pow_z: Basic Arithmetic Functions.
+- (line 122)
++ (line 127)
+ * mpfr_prec_round: Rounding Related Functions.
+ (line 13)
+ * ‘mpfr_prec_t’: Nomenclature and Types.
+@@ -3999,7 +4017,7 @@
+ * mpfr_print_rnd_mode: Rounding Related Functions.
+ (line 71)
+ * mpfr_rec_sqrt: Basic Arithmetic Functions.
+- (line 103)
++ (line 105)
+ * mpfr_regular_p: Comparison Functions.
+ (line 43)
+ * mpfr_reldiff: Compatibility with MPF.
+@@ -4021,11 +4039,11 @@
+ * ‘mpfr_rnd_t’: Nomenclature and Types.
+ (line 34)
+ * mpfr_root: Basic Arithmetic Functions.
+- (line 109)
++ (line 114)
+ * mpfr_round: Integer Related Functions.
+ (line 9)
+-* mpfr_sec: Special Functions. (line 45)
+-* mpfr_sech: Special Functions. (line 109)
++* mpfr_sec: Special Functions. (line 47)
++* mpfr_sech: Special Functions. (line 111)
+ * mpfr_set: Assignment Functions.
+ (line 9)
+ * mpfr_setsign: Miscellaneous Functions.
+@@ -4100,57 +4118,57 @@
+ (line 49)
+ * mpfr_signbit: Miscellaneous Functions.
+ (line 99)
+-* mpfr_sin: Special Functions. (line 30)
+-* mpfr_sinh: Special Functions. (line 96)
+-* mpfr_sinh_cosh: Special Functions. (line 101)
+-* mpfr_sin_cos: Special Functions. (line 35)
++* mpfr_sin: Special Functions. (line 32)
++* mpfr_sinh: Special Functions. (line 98)
++* mpfr_sinh_cosh: Special Functions. (line 103)
++* mpfr_sin_cos: Special Functions. (line 37)
+ * mpfr_si_div: Basic Arithmetic Functions.
+- (line 78)
++ (line 80)
+ * mpfr_si_sub: Basic Arithmetic Functions.
+- (line 31)
++ (line 32)
+ * mpfr_snprintf: Formatted Output Functions.
+ (line 180)
+ * mpfr_sprintf: Formatted Output Functions.
+ (line 170)
+ * mpfr_sqr: Basic Arithmetic Functions.
+- (line 69)
++ (line 71)
+ * mpfr_sqrt: Basic Arithmetic Functions.
+- (line 96)
++ (line 98)
+ * mpfr_sqrt_ui: Basic Arithmetic Functions.
+- (line 97)
++ (line 99)
+ * mpfr_strtofr: Assignment Functions.
+ (line 80)
+ * mpfr_sub: Basic Arithmetic Functions.
+- (line 25)
++ (line 26)
+ * mpfr_subnormalize: Exception Related Functions.
+ (line 60)
+ * mpfr_sub_d: Basic Arithmetic Functions.
+- (line 37)
++ (line 38)
+ * mpfr_sub_q: Basic Arithmetic Functions.
+- (line 43)
++ (line 44)
+ * mpfr_sub_si: Basic Arithmetic Functions.
+- (line 33)
++ (line 34)
+ * mpfr_sub_ui: Basic Arithmetic Functions.
+- (line 29)
++ (line 30)
+ * mpfr_sub_z: Basic Arithmetic Functions.
+- (line 41)
+-* mpfr_sum: Special Functions. (line 252)
++ (line 42)
++* mpfr_sum: Special Functions. (line 262)
+ * mpfr_swap: Assignment Functions.
+ (line 150)
+ * ‘mpfr_t’: Nomenclature and Types.
+ (line 6)
+-* mpfr_tan: Special Functions. (line 31)
+-* mpfr_tanh: Special Functions. (line 97)
++* mpfr_tan: Special Functions. (line 33)
++* mpfr_tanh: Special Functions. (line 99)
+ * mpfr_trunc: Integer Related Functions.
+ (line 10)
+ * mpfr_ui_div: Basic Arithmetic Functions.
+- (line 74)
++ (line 76)
+ * mpfr_ui_pow: Basic Arithmetic Functions.
+- (line 126)
++ (line 131)
+ * mpfr_ui_pow_ui: Basic Arithmetic Functions.
+- (line 124)
++ (line 129)
+ * mpfr_ui_sub: Basic Arithmetic Functions.
+- (line 27)
++ (line 28)
+ * mpfr_underflow_p: Exception Related Functions.
+ (line 132)
+ * mpfr_unordered_p: Comparison Functions.
+@@ -4181,61 +4199,61 @@
+ (line 182)
+ * mpfr_vsprintf: Formatted Output Functions.
+ (line 171)
+-* mpfr_y0: Special Functions. (line 193)
+-* mpfr_y1: Special Functions. (line 194)
+-* mpfr_yn: Special Functions. (line 195)
++* mpfr_y0: Special Functions. (line 199)
++* mpfr_y1: Special Functions. (line 200)
++* mpfr_yn: Special Functions. (line 201)
+ * mpfr_zero_p: Comparison Functions.
+ (line 42)
+-* mpfr_zeta: Special Functions. (line 171)
+-* mpfr_zeta_ui: Special Functions. (line 172)
++* mpfr_zeta: Special Functions. (line 177)
++* mpfr_zeta_ui: Special Functions. (line 178)
+ * mpfr_z_sub: Basic Arithmetic Functions.
+- (line 39)
++ (line 40)
+
+
+ 
+ Tag Table:
+ Node: Top775
+ Node: Copying2007
+-Node: Introduction to MPFR3766
+-Node: Installing MPFR5880
+-Node: Reporting Bugs11323
+-Node: MPFR Basics13353
+-Node: Headers and Libraries13669
+-Node: Nomenclature and Types16828
+-Node: MPFR Variable Conventions18874
+-Node: Rounding Modes20418
+-Ref: ternary value21544
+-Node: Floating-Point Values on Special Numbers23526
+-Node: Exceptions26572
+-Node: Memory Handling29749
+-Node: MPFR Interface30894
+-Node: Initialization Functions33008
+-Node: Assignment Functions40318
+-Node: Combined Initialization and Assignment Functions49673
+-Node: Conversion Functions50974
+-Node: Basic Arithmetic Functions60035
+-Node: Comparison Functions69200
+-Node: Special Functions72687
+-Node: Input and Output Functions86672
+-Node: Formatted Output Functions88644
+-Node: Integer Related Functions98431
+-Node: Rounding Related Functions105051
+-Node: Miscellaneous Functions108888
+-Node: Exception Related Functions117568
+-Node: Compatibility with MPF124386
+-Node: Custom Interface127127
+-Node: Internals131526
+-Node: API Compatibility133066
+-Node: Type and Macro Changes134995
+-Node: Added Functions137844
+-Node: Changed Functions141132
+-Node: Removed Functions145545
+-Node: Other Changes145973
+-Node: Contributors147576
+-Node: References150219
+-Node: GNU Free Documentation License151973
+-Node: Concept Index174562
+-Node: Function and Type Index180659
++Node: Introduction to MPFR3770
++Node: Installing MPFR5884
++Node: Reporting Bugs11327
++Node: MPFR Basics13357
++Node: Headers and Libraries13673
++Node: Nomenclature and Types16832
++Node: MPFR Variable Conventions18894
++Node: Rounding Modes20438
++Ref: ternary value21568
++Node: Floating-Point Values on Special Numbers23554
++Node: Exceptions26813
++Node: Memory Handling29990
++Node: MPFR Interface31135
++Node: Initialization Functions33249
++Node: Assignment Functions40559
++Node: Combined Initialization and Assignment Functions49914
++Node: Conversion Functions51215
++Node: Basic Arithmetic Functions60276
++Node: Comparison Functions69777
++Node: Special Functions73264
++Node: Input and Output Functions87862
++Node: Formatted Output Functions89834
++Node: Integer Related Functions99621
++Node: Rounding Related Functions106241
++Node: Miscellaneous Functions110078
++Node: Exception Related Functions118758
++Node: Compatibility with MPF125576
++Node: Custom Interface128317
++Node: Internals132716
++Node: API Compatibility134260
++Node: Type and Macro Changes136189
++Node: Added Functions139038
++Node: Changed Functions142326
++Node: Removed Functions146739
++Node: Other Changes147167
++Node: Contributors148770
++Node: References151413
++Node: GNU Free Documentation License153167
++Node: Concept Index175760
++Node: Function and Type Index181857
+ 
+ End Tag Table
+
+diff -Naurd mpfr-3.1.3-a/src/lngamma.c mpfr-3.1.3-b/src/lngamma.c
+--- mpfr-3.1.3-a/src/lngamma.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/lngamma.c 2015-07-02 10:49:24.018113593 +0000
+@@ -603,16 +603,17 @@
+ mpfr_get_prec (y), mpfr_log_prec, y, inex));
+
+ /* special cases */
+- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
++ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) ||
++ (MPFR_IS_NEG (x) && mpfr_integer_p (x))))
+ {
+- if (MPFR_IS_NAN (x) || MPFR_IS_NEG (x))
++ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+- else /* lngamma(+Inf) = lngamma(+0) = +Inf */
++ else /* lngamma(+/-Inf) = lngamma(nonpositive integer) = +Inf */
+ {
+- if (MPFR_IS_ZERO (x))
++ if (!MPFR_IS_INF (x))
+ mpfr_set_divby0 ();
+ MPFR_SET_INF (y);
+ MPFR_SET_POS (y);
+@@ -620,8 +621,8 @@
+ }
+ }
+
+- /* if x < 0 and -2k-1 <= x <= -2k, then lngamma(x) = NaN */
+- if (MPFR_IS_NEG (x) && (unit_bit (x) == 0 || mpfr_integer_p (x)))
++ /* if -2k-1 < x < -2k <= 0, then lngamma(x) = NaN */
++ if (MPFR_IS_NEG (x) && unit_bit (x) == 0)
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2015-07-02 10:49:24.038113803 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3"
++#define MPFR_VERSION_STRING "3.1.3-p1"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/version.c 2015-07-02 10:49:24.042113845 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3";
++ return "3.1.3-p1";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tlngamma.c mpfr-3.1.3-b/tests/tlngamma.c
+--- mpfr-3.1.3-a/tests/tlngamma.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tlngamma.c 2015-07-02 10:49:24.018113593 +0000
+@@ -33,7 +33,7 @@
+ special (void)
+ {
+ mpfr_t x, y;
+- int inex;
++ int i, inex;
+
+ mpfr_init (x);
+ mpfr_init (y);
+@@ -46,25 +46,29 @@
+ exit (1);
+ }
+
+- mpfr_set_inf (x, -1);
++ mpfr_set_inf (x, 1);
++ mpfr_clear_flags ();
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (!mpfr_nan_p (y))
++ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || __gmpfr_flags != 0)
+ {
+- printf ("Error for lngamma(-Inf)\n");
++ printf ("Error for lngamma(+Inf)\n");
+ exit (1);
+ }
+
+- mpfr_set_inf (x, 1);
++ mpfr_set_inf (x, -1);
++ mpfr_clear_flags ();
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
++ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || __gmpfr_flags != 0)
+ {
+- printf ("Error for lngamma(+Inf)\n");
++ printf ("Error for lngamma(-Inf)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
++ mpfr_clear_flags ();
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
++ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 ||
++ __gmpfr_flags != MPFR_FLAGS_DIVBY0)
+ {
+ printf ("Error for lngamma(+0)\n");
+ exit (1);
+@@ -72,32 +76,58 @@
+
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_neg (x, x, MPFR_RNDN);
++ mpfr_clear_flags ();
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (!mpfr_nan_p (y))
++ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 ||
++ __gmpfr_flags != MPFR_FLAGS_DIVBY0)
+ {
+ printf ("Error for lngamma(-0)\n");
+ exit (1);
+ }
+
+ mpfr_set_ui (x, 1, MPFR_RNDN);
++ mpfr_clear_flags ();
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
++ if (mpfr_cmp_ui0 (y, 0) || MPFR_IS_NEG (y))
+ {
+ printf ("Error for lngamma(1)\n");
+ exit (1);
+ }
+
+- mpfr_set_si (x, -1, MPFR_RNDN);
+- mpfr_lngamma (y, x, MPFR_RNDN);
+- if (!mpfr_nan_p (y))
++ for (i = 1; i <= 5; i++)
+ {
+- printf ("Error for lngamma(-1)\n");
+- exit (1);
++ int c;
++
++ mpfr_set_si (x, -i, MPFR_RNDN);
++ mpfr_clear_flags ();
++ mpfr_lngamma (y, x, MPFR_RNDN);
++ if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 ||
++ __gmpfr_flags != MPFR_FLAGS_DIVBY0)
++ {
++ printf ("Error for lngamma(-%d)\n", i);
++ exit (1);
++ }
++ if (i & 1)
++ {
++ mpfr_nextabove (x);
++ c = '+';
++ }
++ else
++ {
++ mpfr_nextbelow (x);
++ c = '-';
++ }
++ mpfr_lngamma (y, x, MPFR_RNDN);
++ if (!mpfr_nan_p (y))
++ {
++ printf ("Error for lngamma(-%d%cepsilon)\n", i, c);
++ exit (1);
++ }
+ }
+
+ mpfr_set_ui (x, 2, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+- if (MPFR_IS_NAN (y) || mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
++ if (mpfr_cmp_ui0 (y, 0) || MPFR_IS_NEG (y))
+ {
+ printf ("Error for lngamma(2)\n");
+ exit (1);
+@@ -127,7 +157,7 @@
+ mpfr_set_str (x, CHECK_X2, 10, MPFR_RNDN);
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_str (x, CHECK_Y2, 10, MPFR_RNDN);
+- if (MPFR_IS_NAN (y) || mpfr_cmp (y, x))
++ if (mpfr_cmp0 (y, x))
+ {
+ printf ("mpfr_lngamma("CHECK_X2") is wrong:\n"
+ "expected ");
+@@ -143,7 +173,7 @@
+ mpfr_lngamma (y, x, MPFR_RNDU);
+ mpfr_set_prec (x, 175);
+ mpfr_set_str_binary (x, "0.1010001100011101101011001101110010100001000001000001110011000001101100001111001001000101011011100100010101011110100111110101010100010011010010000101010111001100011000101111E7");
+- if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
++ if (mpfr_cmp0 (x, y))
+ {
+ printf ("Error in mpfr_lngamma (1)\n");
+ exit (1);
+@@ -155,7 +185,7 @@
+ mpfr_lngamma (x, y, MPFR_RNDZ);
+ mpfr_set_prec (y, 21);
+ mpfr_set_str_binary (y, "0.111000101000001100101E9");
+- if (MPFR_IS_NAN (x) || mpfr_cmp (x, y))
++ if (mpfr_cmp0 (x, y))
+ {
+ printf ("Error in mpfr_lngamma (120)\n");
+ printf ("Expected "); mpfr_print_binary (y); puts ("");
+@@ -169,7 +199,7 @@
+ inex = mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 206);
+ mpfr_set_str_binary (x, "0.10000111011000000011100010101001100110001110000111100011000100100110110010001011011110101001111011110110000001010100111011010000000011100110110101100111000111010011110010000100010111101010001101000110101001E13");
+- if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
++ if (mpfr_cmp0 (x, y))
+ {
+ printf ("Error in mpfr_lngamma (768)\n");
+ exit (1);
+@@ -185,7 +215,7 @@
+ mpfr_set_str_binary (x, "0.1100E-66");
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_str_binary (x, "0.1100E6");
+- if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
++ if (mpfr_cmp0 (x, y))
+ {
+ printf ("Error for lngamma(0.1100E-66)\n");
+ exit (1);
+@@ -199,7 +229,7 @@
+ mpfr_lngamma (y, x, MPFR_RNDN);
+ mpfr_set_prec (x, 32);
+ mpfr_set_str_binary (x, "-0.10001000111011111011000010100010E207");
+- if (MPFR_IS_NAN (y) || mpfr_cmp (x, y))
++ if (mpfr_cmp0 (x, y))
+ {
+ printf ("Error for lngamma(-2^199+0.5)\n");
+ printf ("Got ");
diff --git a/patches/mpfr/3.1.3/120-muldiv-2exp-overflow.patch b/patches/mpfr/3.1.3/120-muldiv-2exp-overflow.patch
new file mode 100644
index 0000000..df711fd
--- /dev/null
+++ b/patches/mpfr/3.1.3/120-muldiv-2exp-overflow.patch
@@ -0,0 +1,161 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2015-07-02 10:50:08.046573308 +0000
++++ mpfr-3.1.3-b/PATCHES 2015-07-02 10:50:08.126574142 +0000
+@@ -0,0 +1 @@
++muldiv-2exp-overflow
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-07-02 10:49:24.042113845 +0000
++++ mpfr-3.1.3-b/VERSION 2015-07-02 10:50:08.126574142 +0000
+@@ -1 +1 @@
+-3.1.3-p1
++3.1.3-p2
+diff -Naurd mpfr-3.1.3-a/src/div_2si.c mpfr-3.1.3-b/src/div_2si.c
+--- mpfr-3.1.3-a/src/div_2si.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/div_2si.c 2015-07-02 10:50:08.106573933 +0000
+@@ -49,7 +49,7 @@
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+- else if (MPFR_UNLIKELY(n < 0 && (__gmpfr_emax < MPFR_EMIN_MIN - n ||
++ else if (MPFR_UNLIKELY(n <= 0 && (__gmpfr_emax < MPFR_EMIN_MIN - n ||
+ exp > __gmpfr_emax + n)) )
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y));
+
+diff -Naurd mpfr-3.1.3-a/src/div_2ui.c mpfr-3.1.3-b/src/div_2ui.c
+--- mpfr-3.1.3-a/src/div_2ui.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/div_2ui.c 2015-07-02 10:50:08.106573933 +0000
+@@ -32,7 +32,7 @@
+ rnd_mode),
+ ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inexact));
+
+- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
++ if (MPFR_UNLIKELY (n == 0 || MPFR_IS_SINGULAR (x)))
+ return mpfr_set (y, x, rnd_mode);
+ else
+ {
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-07-02 10:49:24.038113803 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2015-07-02 10:50:08.126574142 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p1"
++#define MPFR_VERSION_STRING "3.1.3-p2"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/mul_2si.c mpfr-3.1.3-b/src/mul_2si.c
+--- mpfr-3.1.3-a/src/mul_2si.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/mul_2si.c 2015-07-02 10:50:08.106573933 +0000
+@@ -39,7 +39,7 @@
+ {
+ mpfr_exp_t exp = MPFR_GET_EXP (x);
+ MPFR_SETRAW (inexact, y, x, exp, rnd_mode);
+- if (MPFR_UNLIKELY( n > 0 && (__gmpfr_emax < MPFR_EMIN_MIN + n ||
++ if (MPFR_UNLIKELY(n >= 0 && (__gmpfr_emax < MPFR_EMIN_MIN + n ||
+ exp > __gmpfr_emax - n)))
+ return mpfr_overflow (y, rnd_mode, MPFR_SIGN(y));
+ else if (MPFR_UNLIKELY(n < 0 && (__gmpfr_emin > MPFR_EMAX_MAX + n ||
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-07-02 10:49:24.042113845 +0000
++++ mpfr-3.1.3-b/src/version.c 2015-07-02 10:50:08.126574142 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p1";
++ return "3.1.3-p2";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tmul_2exp.c mpfr-3.1.3-b/tests/tmul_2exp.c
+--- mpfr-3.1.3-a/tests/tmul_2exp.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tmul_2exp.c 2015-07-02 10:50:08.106573933 +0000
+@@ -242,6 +242,76 @@
+ large (MPFR_EMAX_MAX);
+ }
+
++/* Cases where the function overflows on n = 0 when rounding is like
++ away from zero. */
++static void
++overflow0 (mpfr_exp_t emax)
++{
++ mpfr_exp_t old_emax;
++ mpfr_t x, y1, y2;
++ int neg, r, op;
++ static char *sop[4] = { "mul_2ui", "mul_2si", "div_2ui", "div_2si" };
++
++ old_emax = mpfr_get_emax ();
++ set_emax (emax);
++
++ mpfr_init2 (x, 8);
++ mpfr_inits2 (6, y1, y2, (mpfr_ptr) 0);
++
++ mpfr_set_inf (x, 1);
++ mpfr_nextbelow (x);
++
++ for (neg = 0; neg <= 1; neg++)
++ {
++ RND_LOOP (r)
++ {
++ int inex1, inex2;
++ unsigned int flags1, flags2;
++
++ /* Even if there isn't an overflow (rounding ~ toward zero),
++ the result is the same as the one of an overflow. */
++ inex1 = mpfr_overflow (y1, (mpfr_rnd_t) r, neg ? -1 : 1);
++ flags1 = MPFR_FLAGS_INEXACT;
++ if (mpfr_inf_p (y1))
++ flags1 |= MPFR_FLAGS_OVERFLOW;
++ for (op = 0; op < 4; op++)
++ {
++ mpfr_clear_flags ();
++ inex2 =
++ op == 0 ? mpfr_mul_2ui (y2, x, 0, (mpfr_rnd_t) r) :
++ op == 1 ? mpfr_mul_2si (y2, x, 0, (mpfr_rnd_t) r) :
++ op == 2 ? mpfr_div_2ui (y2, x, 0, (mpfr_rnd_t) r) :
++ op == 3 ? mpfr_div_2si (y2, x, 0, (mpfr_rnd_t) r) :
++ (MPFR_ASSERTN (0), 0);
++ flags2 = __gmpfr_flags;
++ if (!(mpfr_equal_p (y1, y2) &&
++ SAME_SIGN (inex1, inex2) &&
++ flags1 == flags2))
++ {
++ printf ("Error in overflow0 for %s, mpfr_%s, emax = %"
++ MPFR_EXP_FSPEC "d,\nx = ",
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r), sop[op],
++ (mpfr_eexp_t) emax);
++ mpfr_dump (x);
++ printf ("Expected ");
++ mpfr_dump (y1);
++ printf (" with inex = %d, flags =", inex1);
++ flags_out (flags1);
++ printf ("Got ");
++ mpfr_dump (y2);
++ printf (" with inex = %d, flags =", inex2);
++ flags_out (flags2);
++ exit (1);
++ }
++ }
++ }
++ mpfr_neg (x, x, MPFR_RNDN);
++ }
++
++ mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
++ set_emax (old_emax);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -334,6 +404,11 @@
+ underflow0 ();
+ large0 ();
+
++ if (mpfr_get_emax () != MPFR_EMAX_MAX)
++ overflow0 (mpfr_get_emax ());
++ overflow0 (MPFR_EMAX_MAX);
++ overflow0 (-1);
++
+ tests_end_mpfr ();
+ return 0;
+ }
diff --git a/patches/mpfr/3.1.3/130-muldiv-2exp-underflow.patch b/patches/mpfr/3.1.3/130-muldiv-2exp-underflow.patch
new file mode 100644
index 0000000..c7be09f
--- /dev/null
+++ b/patches/mpfr/3.1.3/130-muldiv-2exp-underflow.patch
@@ -0,0 +1,217 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2015-07-17 08:54:48.592799981 +0000
++++ mpfr-3.1.3-b/PATCHES 2015-07-17 08:54:48.616811495 +0000
+@@ -0,0 +1 @@
++muldiv-2exp-underflow
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-07-02 10:50:08.126574142 +0000
++++ mpfr-3.1.3-b/VERSION 2015-07-17 08:54:48.616811495 +0000
+@@ -1 +1 @@
+-3.1.3-p2
++3.1.3-p3
+diff -Naurd mpfr-3.1.3-a/src/div_2si.c mpfr-3.1.3-b/src/div_2si.c
+--- mpfr-3.1.3-a/src/div_2si.c 2015-07-02 10:50:08.106573933 +0000
++++ mpfr-3.1.3-b/src/div_2si.c 2015-07-17 08:54:48.608807656 +0000
+@@ -45,7 +45,8 @@
+ if (rnd_mode == MPFR_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX - (n - 1) ||
+ exp < __gmpfr_emin + (n - 1) ||
+- (inexact >= 0 && mpfr_powerof2_raw (y))))
++ ((MPFR_IS_NEG (y) ? inexact <= 0 : inexact >= 0) &&
++ mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+diff -Naurd mpfr-3.1.3-a/src/div_2ui.c mpfr-3.1.3-b/src/div_2ui.c
+--- mpfr-3.1.3-a/src/div_2ui.c 2015-07-02 10:50:08.106573933 +0000
++++ mpfr-3.1.3-b/src/div_2ui.c 2015-07-17 08:54:48.608807656 +0000
+@@ -44,7 +44,9 @@
+ if (MPFR_UNLIKELY (n >= diffexp)) /* exp - n <= emin - 1 */
+ {
+ if (rnd_mode == MPFR_RNDN &&
+- (n > diffexp || (inexact >= 0 && mpfr_powerof2_raw (y))))
++ (n > diffexp ||
++ ((MPFR_IS_NEG (y) ? inexact <= 0 : inexact >= 0) &&
++ mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN (y));
+ }
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-07-02 10:50:08.126574142 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2015-07-17 08:54:48.616811495 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p2"
++#define MPFR_VERSION_STRING "3.1.3-p3"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/mul_2si.c mpfr-3.1.3-b/src/mul_2si.c
+--- mpfr-3.1.3-a/src/mul_2si.c 2015-07-02 10:50:08.106573933 +0000
++++ mpfr-3.1.3-b/src/mul_2si.c 2015-07-17 08:54:48.608807656 +0000
+@@ -48,7 +48,8 @@
+ if (rnd_mode == MPFR_RNDN &&
+ (__gmpfr_emin > MPFR_EMAX_MAX + (n + 1) ||
+ exp < __gmpfr_emin - (n + 1) ||
+- (inexact >= 0 && mpfr_powerof2_raw (y))))
++ ((MPFR_IS_NEG (y) ? inexact <= 0 : inexact >= 0) &&
++ mpfr_powerof2_raw (y))))
+ rnd_mode = MPFR_RNDZ;
+ return mpfr_underflow (y, rnd_mode, MPFR_SIGN(y));
+ }
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-07-02 10:50:08.126574142 +0000
++++ mpfr-3.1.3-b/src/version.c 2015-07-17 08:54:48.616811495 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p2";
++ return "3.1.3-p3";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tmul_2exp.c mpfr-3.1.3-b/tests/tmul_2exp.c
+--- mpfr-3.1.3-a/tests/tmul_2exp.c 2015-07-02 10:50:08.106573933 +0000
++++ mpfr-3.1.3-b/tests/tmul_2exp.c 2015-07-17 08:54:48.608807656 +0000
+@@ -50,77 +50,82 @@
+ {
+ mpfr_t x, y, z1, z2;
+ mpfr_exp_t emin;
+- int i, k;
++ int i, k, s;
+ int prec;
+ int rnd;
+ int div;
+ int inex1, inex2;
+ unsigned int flags1, flags2;
+
+- /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
+- * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
+- * by comparing the result with the one of a simple division.
++ /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e) with
++ * emin = e, x = s * (1 + i/16), i in { -1, 0, 1 }, s in { -1, 1 }, and
++ * k = 1 to 4, by comparing the result with the one of a simple division.
+ */
+ emin = mpfr_get_emin ();
+ set_emin (e);
+ mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
+ for (i = 15; i <= 17; i++)
+- {
+- inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
+- MPFR_ASSERTN (inex1 == 0);
+- for (prec = 6; prec >= 3; prec -= 3)
+- {
+- mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
+- RND_LOOP (rnd)
+- for (k = 1; k <= 4; k++)
+- {
+- /* The following one is assumed to be correct. */
+- inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
+- MPFR_ASSERTN (inex1 == 0);
+- inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
+- MPFR_ASSERTN (inex1 == 0);
+- mpfr_clear_flags ();
+- /* Do not use mpfr_div_ui to avoid the optimization
+- by mpfr_div_2si. */
+- inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
+- flags1 = __gmpfr_flags;
+-
+- for (div = 0; div <= 2; div++)
++ for (s = 1; s >= -1; s -= 2)
++ {
++ inex1 = mpfr_set_si_2exp (x, s * i, -4, MPFR_RNDN);
++ MPFR_ASSERTN (inex1 == 0);
++ for (prec = 6; prec >= 3; prec -= 3)
++ {
++ mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
++ RND_LOOP (rnd)
++ for (k = 1; k <= 4; k++)
+ {
++ /* The following one is assumed to be correct. */
++ inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
++ MPFR_ASSERTN (inex1 == 0);
++ inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
++ MPFR_ASSERTN (inex1 == 0);
+ mpfr_clear_flags ();
+- inex2 = div == 0 ?
+- mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
+- mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
+- mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
+- flags2 = __gmpfr_flags;
+- if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+- mpfr_equal_p (z1, z2))
+- continue;
+- printf ("Error in underflow(");
+- if (e == MPFR_EMIN_MIN)
+- printf ("MPFR_EMIN_MIN");
+- else if (e == emin)
+- printf ("default emin");
+- else if (e >= LONG_MIN)
+- printf ("%ld", (long) e);
+- else
+- printf ("<LONG_MIN");
+- printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
+- "%s\n", div == 0 ? "mul_2si" : div == 1 ?
+- "div_2si" : "div_2ui", i, prec, k,
+- mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
+- printf ("Expected ");
+- mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
+- printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
+- printf ("Got ");
+- mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
+- printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
+- exit (1);
+- } /* div */
+- } /* k */
+- mpfr_clears (z1, z2, (mpfr_ptr) 0);
+- } /* prec */
+- } /* i */
++ /* Do not use mpfr_div_ui to avoid the optimization
++ by mpfr_div_2si. */
++ inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
++ flags1 = __gmpfr_flags;
++
++ for (div = 0; div <= 2; div++)
++ {
++ mpfr_clear_flags ();
++ inex2 =
++ div == 0 ?
++ mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) :
++ div == 1 ?
++ mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
++ mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
++ flags2 = __gmpfr_flags;
++ if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
++ mpfr_equal_p (z1, z2))
++ continue;
++ printf ("Error in underflow(");
++ if (e == MPFR_EMIN_MIN)
++ printf ("MPFR_EMIN_MIN");
++ else if (e == emin)
++ printf ("default emin");
++ else if (e >= LONG_MIN)
++ printf ("%ld", (long) e);
++ else
++ printf ("<LONG_MIN");
++ printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d,"
++ " %s\n", div == 0 ? "mul_2si" : div == 1 ?
++ "div_2si" : "div_2ui", s * i, prec, k,
++ mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
++ printf ("Expected ");
++ mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
++ printf (", inex = %d, flags = %u\n",
++ SIGN (inex1), flags1);
++ printf ("Got ");
++ mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
++ printf (", inex = %d, flags = %u\n",
++ SIGN (inex2), flags2);
++ exit (1);
++ } /* div */
++ } /* k */
++ mpfr_clears (z1, z2, (mpfr_ptr) 0);
++ } /* prec */
++ } /* i */
+ mpfr_clears (x, y, (mpfr_ptr) 0);
+ set_emin (emin);
+ }
diff --git a/patches/mpfr/3.1.3/140-frexp.patch b/patches/mpfr/3.1.3/140-frexp.patch
new file mode 100644
index 0000000..e0d5e09
--- /dev/null
+++ b/patches/mpfr/3.1.3/140-frexp.patch
@@ -0,0 +1,204 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2015-07-17 08:58:21.094987384 +0000
++++ mpfr-3.1.3-b/PATCHES 2015-07-17 08:58:21.118986898 +0000
+@@ -0,0 +1 @@
++frexp
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-07-17 08:54:48.616811495 +0000
++++ mpfr-3.1.3-b/VERSION 2015-07-17 08:58:21.118986898 +0000
+@@ -1 +1 @@
+-3.1.3-p3
++3.1.3-p4
+diff -Naurd mpfr-3.1.3-a/src/frexp.c mpfr-3.1.3-b/src/frexp.c
+--- mpfr-3.1.3-a/src/frexp.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/frexp.c 2015-07-17 08:58:21.106987142 +0000
+@@ -26,6 +26,13 @@
+ mpfr_frexp (mpfr_exp_t *exp, mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
+ {
+ int inex;
++ unsigned int saved_flags = __gmpfr_flags;
++ MPFR_BLOCK_DECL (flags);
++
++ MPFR_LOG_FUNC
++ (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
++ ("y[%Pu]=%.*Rg exp=%" MPFR_EXP_FSPEC "d inex=%d", mpfr_get_prec (y),
++ mpfr_log_prec, y, (mpfr_eexp_t) *exp, inex));
+
+ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(x)))
+ {
+@@ -49,8 +56,32 @@
+ }
+ }
+
+- inex = mpfr_set (y, x, rnd);
++ MPFR_BLOCK (flags, inex = mpfr_set (y, x, rnd));
++ __gmpfr_flags = saved_flags;
++
++ /* Possible overflow due to the rounding, no possible underflow. */
++
++ if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags)))
++ {
++ int inex2;
++
++ /* An overflow here means that the exponent of y would be larger than
++ the one of x, thus x would be rounded to the next power of 2, and
++ the returned y should be 1/2 in absolute value, rounded (i.e. with
++ possible underflow or overflow). This also implies that x and y are
++ different objects, so that the exponent of x has not been lost. */
++ MPFR_LOG_MSG (("Internal overflow\n", 0));
++ MPFR_ASSERTD (x != y);
++ *exp = MPFR_GET_EXP (x) + 1;
++ inex2 = mpfr_set_si_2exp (y, MPFR_INT_SIGN (x), -1, rnd);
++ MPFR_LOG_MSG (("inex=%d inex2=%d\n", inex, inex2));
++ if (inex2 != 0)
++ inex = inex2;
++ MPFR_RET (inex);
++ }
++
+ *exp = MPFR_GET_EXP (y);
+- MPFR_SET_EXP (y, 0);
++ /* Do not use MPFR_SET_EXP because the range has not been checked yet. */
++ MPFR_EXP (y) = 0;
+ return mpfr_check_range (y, inex, rnd);
+ }
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-07-17 08:54:48.616811495 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2015-07-17 08:58:21.114986979 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p3"
++#define MPFR_VERSION_STRING "3.1.3-p4"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-07-17 08:54:48.616811495 +0000
++++ mpfr-3.1.3-b/src/version.c 2015-07-17 08:58:21.118986898 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p3";
++ return "3.1.3-p4";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tfrexp.c mpfr-3.1.3-b/tests/tfrexp.c
+--- mpfr-3.1.3-a/tests/tfrexp.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tfrexp.c 2015-07-17 08:58:21.106987142 +0000
+@@ -129,12 +129,115 @@
+ mpfr_clear (x);
+ }
+
++static void check1 (void)
++{
++ mpfr_exp_t emin, emax, e;
++ mpfr_t x, y1, y2;
++ int r, neg, red;
++
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++ set_emin (MPFR_EMIN_MIN);
++ set_emax (MPFR_EMAX_MAX);
++
++ mpfr_init2 (x, 7);
++ mpfr_inits2 (4, y1, y2, (mpfr_ptr) 0);
++
++ mpfr_set_ui_2exp (x, 1, -2, MPFR_RNDN);
++ while (mpfr_regular_p (x))
++ {
++ /* Test the exponents up to 3 and with the maximum exponent
++ (to check potential intermediate overflow). */
++ if (MPFR_GET_EXP (x) == 4)
++ mpfr_set_exp (x, MPFR_EMAX_MAX);
++ e = MPFR_GET_EXP (x);
++ for (neg = 0; neg < 2; neg++)
++ {
++ RND_LOOP (r)
++ {
++ int inex1, inex2;
++ mpfr_exp_t e1, e2;
++ unsigned int flags1, flags2;
++
++ for (red = 0; red < 2; red++)
++ {
++ if (red)
++ {
++ /* e1: exponent of the rounded value of x. */
++ MPFR_ASSERTN (e1 == e || e1 == e + 1);
++ set_emin (e);
++ set_emax (e);
++ mpfr_clear_flags ();
++ inex1 = e1 < 0 ?
++ mpfr_mul_2ui (y1, x, -e1, (mpfr_rnd_t) r) :
++ mpfr_div_2ui (y1, x, e1, (mpfr_rnd_t) r);
++ flags1 = __gmpfr_flags;
++ }
++ else
++ {
++ inex1 = mpfr_set (y1, x, (mpfr_rnd_t) r);
++ e1 = MPFR_IS_INF (y1) ? e + 1 : MPFR_GET_EXP (y1);
++ flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
++ }
++ mpfr_clear_flags ();
++ inex2 = mpfr_frexp (&e2, y2, x, (mpfr_rnd_t) r);
++ flags2 = __gmpfr_flags;
++ set_emin (MPFR_EMIN_MIN);
++ set_emax (MPFR_EMAX_MAX);
++ if ((!red || e == 0) &&
++ (! mpfr_regular_p (y2) || MPFR_GET_EXP (y2) != 0))
++ {
++ printf ("Error in check1 for %s, red = %d, x = ",
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r), red);
++ mpfr_dump (x);
++ printf ("Expected 1/2 <= |y| < 1, got y = ");
++ mpfr_dump (y2);
++ exit (1);
++ }
++ if (!red)
++ {
++ if (e2 > 0)
++ mpfr_mul_2ui (y2, y2, e2, MPFR_RNDN);
++ else if (e2 < 0)
++ mpfr_div_2ui (y2, y2, -e2, MPFR_RNDN);
++ }
++ if (! (SAME_SIGN (inex1, inex2) &&
++ mpfr_equal_p (y1, y2) &&
++ flags1 == flags2))
++ {
++ printf ("Error in check1 for %s, red = %d, x = ",
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r), red);
++ mpfr_dump (x);
++ printf ("Expected y1 = ");
++ mpfr_dump (y1);
++ printf ("Got y2 = ");
++ mpfr_dump (y2);
++ printf ("Expected inex ~= %d, got %d\n", inex1, inex2);
++ printf ("Expected flags:");
++ flags_out (flags1);
++ printf ("Got flags: ");
++ flags_out (flags2);
++ exit (1);
++ }
++ }
++ }
++ mpfr_neg (x, x, MPFR_RNDN);
++ }
++ mpfr_nextabove (x);
++ }
++
++ mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
++ set_emin (emin);
++ set_emax (emax);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+ tests_start_mpfr ();
+
+ check_special ();
++ check1 ();
+
+ tests_end_mpfr ();
+ return 0;
diff --git a/patches/mpfr/3.1.3/150-divhigh-basecase.patch b/patches/mpfr/3.1.3/150-divhigh-basecase.patch
new file mode 100644
index 0000000..ef8d891
--- /dev/null
+++ b/patches/mpfr/3.1.3/150-divhigh-basecase.patch
@@ -0,0 +1,131 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2015-10-29 13:47:46.735901185 +0000
++++ mpfr-3.1.3-b/PATCHES 2015-10-29 13:47:46.763900609 +0000
+@@ -0,0 +1 @@
++divhigh-basecase
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-07-17 08:58:21.118986898 +0000
++++ mpfr-3.1.3-b/VERSION 2015-10-29 13:47:46.763900609 +0000
+@@ -1 +1 @@
+-3.1.3-p4
++3.1.3-p5
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-07-17 08:58:21.114986979 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2015-10-29 13:47:46.759900692 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p4"
++#define MPFR_VERSION_STRING "3.1.3-p5"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/mulders.c mpfr-3.1.3-b/src/mulders.c
+--- mpfr-3.1.3-a/src/mulders.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/mulders.c 2015-10-29 13:47:46.751900855 +0000
+@@ -236,9 +236,10 @@
+ that in addition to the limb np[n-1] to reduce, we have at least 2
+ extra limbs, thus accessing np[n-3] is valid. */
+
+- /* warning: we can have np[n-1]=d1 and np[n-2]=d0, but since {np,n} < D,
+- the largest possible partial quotient is B-1 */
+- if (MPFR_UNLIKELY(np[n - 1] == d1 && np[n - 2] == d0))
++ /* Warning: we can have np[n-1]>d1 or (np[n-1]=d1 and np[n-2]>=d0) here,
++ since we truncate the divisor at each step, but since {np,n} < D
++ originally, the largest possible partial quotient is B-1. */
++ if (MPFR_UNLIKELY(np[n-1] > d1 || (np[n-1] == d1 && np[n-2] >= d0)))
+ q2 = ~ (mp_limb_t) 0;
+ else
+ udiv_qr_3by2 (q2, q1, q0, np[n - 1], np[n - 2], np[n - 3],
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-07-17 08:58:21.118986898 +0000
++++ mpfr-3.1.3-b/src/version.c 2015-10-29 13:47:46.763900609 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p4";
++ return "3.1.3-p5";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tdiv.c mpfr-3.1.3-b/tests/tdiv.c
+--- mpfr-3.1.3-a/tests/tdiv.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tdiv.c 2015-10-29 13:47:46.751900855 +0000
+@@ -1099,6 +1099,69 @@
+ mpfr_set_emax (old_emax);
+ }
+
++/* Bug in mpfr_divhigh_n_basecase when all limbs of q (except the most
++ significant one) are B-1 where B=2^GMP_NUMB_BITS. Since we truncate
++ the divisor at each step, it might happen at some point that
++ (np[n-1],np[n-2]) > (d1,d0), and not only the equality.
++ Reported by Ricky Farr
++ <https://sympa.inria.fr/sympa/arc/mpfr/2015-10/msg00023.html>
++ To get a failure, a MPFR_DIVHIGH_TAB entry below the MPFR_DIV_THRESHOLD
++ limit must have a value 0. With most mparam.h files, this cannot occur. */
++static void
++test_20151023 (void)
++{
++ mpfr_prec_t p;
++ mpfr_t n, d, q, q0;
++ int inex, i;
++
++ for (p = GMP_NUMB_BITS; p <= 2000; p++)
++ {
++ mpfr_init2 (n, 2*p);
++ mpfr_init2 (d, p);
++ mpfr_init2 (q, p);
++ mpfr_init2 (q0, GMP_NUMB_BITS);
++
++ /* generate a random divisor of p bits */
++ mpfr_urandomb (d, RANDS);
++ /* generate a random quotient of GMP_NUMB_BITS bits */
++ mpfr_urandomb (q0, RANDS);
++ /* zero-pad the quotient to p bits */
++ inex = mpfr_prec_round (q0, p, MPFR_RNDN);
++ MPFR_ASSERTN(inex == 0);
++
++ for (i = 0; i < 3; i++)
++ {
++ /* i=0: try with the original quotient xxx000...000
++ i=1: try with the original quotient minus one ulp
++ i=2: try with the original quotient plus one ulp */
++ if (i == 1)
++ mpfr_nextbelow (q0);
++ else if (i == 2)
++ {
++ mpfr_nextabove (q0);
++ mpfr_nextabove (q0);
++ }
++
++ inex = mpfr_mul (n, d, q0, MPFR_RNDN);
++ MPFR_ASSERTN(inex == 0);
++ mpfr_nextabove (n);
++ mpfr_div (q, n, d, MPFR_RNDN);
++ MPFR_ASSERTN(mpfr_cmp (q, q0) == 0);
++
++ inex = mpfr_mul (n, d, q0, MPFR_RNDN);
++ MPFR_ASSERTN(inex == 0);
++ mpfr_nextbelow (n);
++ mpfr_div (q, n, d, MPFR_RNDN);
++ MPFR_ASSERTN(mpfr_cmp (q, q0) == 0);
++ }
++
++ mpfr_clear (n);
++ mpfr_clear (d);
++ mpfr_clear (q);
++ mpfr_clear (q0);
++ }
++}
++
+ #define TEST_FUNCTION test_div
+ #define TWO_ARGS
+ #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
+@@ -1219,6 +1282,7 @@
+ consistency ();
+ test_20070603 ();
+ test_20070628 ();
++ test_20151023 ();
+ test_generic (2, 800, 50);
+ test_extreme ();
+
diff --git a/patches/mpfr/3.1.3/160-jn.patch b/patches/mpfr/3.1.3/160-jn.patch
new file mode 100644
index 0000000..e7d04fa
--- /dev/null
+++ b/patches/mpfr/3.1.3/160-jn.patch
@@ -0,0 +1,71 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:10:03.358066124 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:10:03.414066216 +0000
+@@ -0,0 +1 @@
++jn
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2015-10-29 13:47:46.763900609 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:10:03.414066216 +0000
+@@ -1 +1 @@
+-3.1.3-p5
++3.1.3-p6
+diff -Naurd mpfr-3.1.3-a/src/jyn_asympt.c mpfr-3.1.3-b/src/jyn_asympt.c
+--- mpfr-3.1.3-a/src/jyn_asympt.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/jyn_asympt.c 2016-02-15 15:10:03.394066183 +0000
+@@ -253,9 +253,9 @@
+ break;
+ if (diverge != 0)
+ {
+- mpfr_set (c, z, r); /* will force inex=0 below, which means the
+- asymptotic expansion failed */
+- break;
++ MPFR_ZIV_FREE (loop);
++ mpfr_clear (c);
++ return 0; /* means that the asymptotic expansion failed */
+ }
+ MPFR_ZIV_NEXT (loop, w);
+ }
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2015-10-29 13:47:46.759900692 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:10:03.410066210 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p5"
++#define MPFR_VERSION_STRING "3.1.3-p6"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2015-10-29 13:47:46.763900609 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:10:03.414066216 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p5";
++ return "3.1.3-p6";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tj0.c mpfr-3.1.3-b/tests/tj0.c
+--- mpfr-3.1.3-a/tests/tj0.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tj0.c 2016-02-15 15:10:03.394066183 +0000
+@@ -99,6 +99,18 @@
+ mpfr_j0 (y, x, MPFR_RNDN);
+ MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_ui_2exp (y, 41, -11) == 0);
+
++ /* Bug reported by Fredrik Johansson on 19 Jan 2016 */
++ mpfr_set_prec (x, 53);
++ mpfr_set_str (x, "0x4.3328p+0", 0, MPFR_RNDN);
++ mpfr_set_prec (y, 2);
++ mpfr_j0 (y, x, MPFR_RNDD);
++ /* y should be -0.5 */
++ MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_si_2exp (y, -1, -1) == 0);
++ mpfr_set_prec (y, 3);
++ mpfr_j0 (y, x, MPFR_RNDD);
++ /* y should be -0.4375 */
++ MPFR_ASSERTN (! mpfr_nan_p (y) && mpfr_cmp_si_2exp (y, -7, -4) == 0);
++
+ /* Case for which s = 0 in mpfr_jn */
+ mpfr_set_prec (x, 44);
+ mpfr_set_prec (y, 44);
diff --git a/patches/mpfr/3.1.3/170-zeta.patch b/patches/mpfr/3.1.3/170-zeta.patch
new file mode 100644
index 0000000..12faf1d
--- /dev/null
+++ b/patches/mpfr/3.1.3/170-zeta.patch
@@ -0,0 +1,125 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:11:00.898156344 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:11:00.966156445 +0000
+@@ -0,0 +1 @@
++zeta
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:10:03.414066216 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:11:00.966156445 +0000
+@@ -1 +1 @@
+-3.1.3-p6
++3.1.3-p7
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:10:03.410066210 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:11:00.962156439 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p6"
++#define MPFR_VERSION_STRING "3.1.3-p7"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:10:03.414066216 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:11:00.966156445 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p6";
++ return "3.1.3-p7";
+ }
+diff -Naurd mpfr-3.1.3-a/src/zeta.c mpfr-3.1.3-b/src/zeta.c
+--- mpfr-3.1.3-a/src/zeta.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/zeta.c 2016-02-15 15:11:00.942156410 +0000
+@@ -377,8 +377,8 @@
+ }
+ }
+
+- /* Check for case s= 1 before changing the exponent range */
+- if (mpfr_cmp (s, __gmpfr_one) ==0)
++ /* Check for case s=1 before changing the exponent range */
++ if (mpfr_cmp (s, __gmpfr_one) == 0)
+ {
+ MPFR_SET_INF (z);
+ MPFR_SET_POS (z);
+@@ -420,7 +420,7 @@
+ MPFR_ZIV_INIT (loop, prec1);
+ for (;;)
+ {
+- mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN);/* s1 = 1-s */
++ mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */
+ mpfr_zeta_pos (z_pre, s1, MPFR_RNDN); /* zeta(1-s) */
+ mpfr_gamma (y, s1, MPFR_RNDN); /* gamma(1-s) */
+ if (MPFR_IS_INF (y)) /* Zeta(s) < 0 for -4k-2 < s < -4k,
+@@ -432,17 +432,32 @@
+ break;
+ }
+ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN); /* gamma(1-s)*zeta(1-s) */
+- mpfr_const_pi (p, MPFR_RNDD);
+- mpfr_mul (y, s, p, MPFR_RNDN);
+- mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* s*Pi/2 */
+- mpfr_sin (y, y, MPFR_RNDN); /* sin(Pi*s/2) */
+- mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
++
++ mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */
++
++ /* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */
+ mpfr_mul_2ui (y, p, 1, MPFR_RNDN); /* 2*Pi */
+ mpfr_neg (s1, s1, MPFR_RNDN); /* s-1 */
+ mpfr_pow (y, y, s1, MPFR_RNDN); /* (2*Pi)^(s-1) */
+ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
+ mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN);
+
++ /* multiply z_pre by sin(Pi*s/2) */
++ mpfr_mul (y, s, p, MPFR_RNDN);
++ mpfr_div_2ui (p, y, 1, MPFR_RNDN); /* p = s*Pi/2 */
++ mpfr_sin (y, p, MPFR_RNDN); /* y = sin(Pi*s/2) */
++ if (MPFR_GET_EXP(y) < 0) /* take account of cancellation in sin(p) */
++ {
++ mpfr_t t;
++ mpfr_init2 (t, prec1 - MPFR_GET_EXP(y));
++ mpfr_const_pi (t, MPFR_RNDD);
++ mpfr_mul (t, s, t, MPFR_RNDN);
++ mpfr_div_2ui (t, t, 1, MPFR_RNDN);
++ mpfr_sin (y, t, MPFR_RNDN);
++ mpfr_clear (t);
++ }
++ mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
++
+ if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
+ rnd_mode)))
+ break;
+diff -Naurd mpfr-3.1.3-a/tests/tzeta.c mpfr-3.1.3-b/tests/tzeta.c
+--- mpfr-3.1.3-a/tests/tzeta.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tzeta.c 2016-02-15 15:11:00.942156410 +0000
+@@ -394,6 +394,27 @@
+ mpfr_nextabove (s);
+ MPFR_ASSERTN (mpfr_equal_p (z, s) && inex > 0);
+
++ /* bug reported by Fredrik Johansson on 19 Jan 2016 */
++ mpfr_set_prec (s, 536);
++ mpfr_set_ui_2exp (s, 1, -424, MPFR_RNDN);
++ mpfr_sub_ui (s, s, 128, MPFR_RNDN); /* -128 + 2^(-424) */
++ for (prec = 6; prec <= 536; prec += 8) /* should go through 318 */
++ {
++ mpfr_set_prec (z, prec);
++ mpfr_zeta (z, s, MPFR_RNDD);
++ mpfr_set_prec (y, prec + 10);
++ mpfr_zeta (y, s, MPFR_RNDD);
++ mpfr_prec_round (y, prec, MPFR_RNDD);
++ if (! mpfr_equal_p (z, y))
++ {
++ printf ("mpfr_zeta fails near -128 for inprec=%lu outprec=%lu\n",
++ (unsigned long) mpfr_get_prec (s), (unsigned long) prec);
++ printf ("expected "); mpfr_dump (y);
++ printf ("got "); mpfr_dump (z);
++ exit (1);
++ }
++ }
++
+ mpfr_clear (s);
+ mpfr_clear (y);
+ mpfr_clear (z);
diff --git a/patches/mpfr/3.1.3/180-sqrt.patch b/patches/mpfr/3.1.3/180-sqrt.patch
new file mode 100644
index 0000000..4887009
--- /dev/null
+++ b/patches/mpfr/3.1.3/180-sqrt.patch
@@ -0,0 +1,97 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:12:59.450314624 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:12:59.510314695 +0000
+@@ -0,0 +1 @@
++sqrt
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:11:00.966156445 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:12:59.510314695 +0000
+@@ -1 +1 @@
+-3.1.3-p7
++3.1.3-p8
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:11:00.962156439 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:12:59.510314695 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p7"
++#define MPFR_VERSION_STRING "3.1.3-p8"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/sqrt.c mpfr-3.1.3-b/src/sqrt.c
+--- mpfr-3.1.3-a/src/sqrt.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/sqrt.c 2016-02-15 15:12:59.490314671 +0000
+@@ -211,10 +211,11 @@
+ rsize --;
+ sh = 0;
+ }
++ /* now rsize = MPFR_LIMB_SIZE(r) */
+ if (mpn_add_1 (rp0, rp, rsize, MPFR_LIMB_ONE << sh))
+ {
+ expr ++;
+- rp[rsize - 1] = MPFR_LIMB_HIGHBIT;
++ rp0[rsize - 1] = MPFR_LIMB_HIGHBIT;
+ }
+ goto end;
+
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:11:00.966156445 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:12:59.510314695 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p7";
++ return "3.1.3-p8";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tsqrt.c mpfr-3.1.3-b/tests/tsqrt.c
+--- mpfr-3.1.3-a/tests/tsqrt.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tsqrt.c 2016-02-15 15:12:59.490314671 +0000
+@@ -569,6 +569,35 @@
+ mpfr_clear (y);
+ }
+
++/* Bug reported by Fredrik Johansson, occurring when:
++ - the precision of the result is a multiple of the number of bits
++ per word (GMP_NUMB_BITS),
++ - the rounding mode is to nearest (MPFR_RNDN),
++ - internally, the result has to be rounded up to a power of 2.
++*/
++static void
++bug20160120 (void)
++{
++ mpfr_t x, y;
++
++ mpfr_init2 (x, 4 * GMP_NUMB_BITS);
++ mpfr_init2 (y, GMP_NUMB_BITS);
++
++ mpfr_set_ui (x, 1, MPFR_RNDN);
++ mpfr_nextbelow (x);
++ mpfr_sqrt (y, x, MPFR_RNDN);
++ MPFR_ASSERTN(mpfr_check (y));
++ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
++
++ mpfr_set_prec (y, 2 * GMP_NUMB_BITS);
++ mpfr_sqrt (y, x, MPFR_RNDN);
++ MPFR_ASSERTN(mpfr_check (y));
++ MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
++
++ mpfr_clear(x);
++ mpfr_clear(y);
++}
++
+ #define TEST_FUNCTION test_sqrt
+ #define TEST_RANDOM_POS 8
+ #include "tgeneric.c"
+@@ -704,6 +733,8 @@
+ data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt");
+ bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50);
+
++ bug20160120 ();
++
+ tests_end_mpfr ();
+ return 0;
+ }
diff --git a/patches/mpfr/3.1.3/190-si-ops.patch b/patches/mpfr/3.1.3/190-si-ops.patch
new file mode 100644
index 0000000..e4df233
--- /dev/null
+++ b/patches/mpfr/3.1.3/190-si-ops.patch
@@ -0,0 +1,107 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:17:39.214577503 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:17:39.282577552 +0000
+@@ -0,0 +1 @@
++si-ops
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:12:59.510314695 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:17:39.282577552 +0000
+@@ -1 +1 @@
+-3.1.3-p8
++3.1.3-p9
+diff -Naurd mpfr-3.1.3-a/src/div_ui.c mpfr-3.1.3-b/src/div_ui.c
+--- mpfr-3.1.3-a/src/div_ui.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/div_ui.c 2016-02-15 15:17:39.258577534 +0000
+@@ -274,7 +274,8 @@
+ res = mpfr_div_ui (y, x, u, rnd_mode);
+ else
+ {
+- res = -mpfr_div_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
++ res = - mpfr_div_ui (y, x, - (unsigned long) u,
++ MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:12:59.510314695 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:17:39.282577552 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p8"
++#define MPFR_VERSION_STRING "3.1.3-p9"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/mul_ui.c mpfr-3.1.3-b/src/mul_ui.c
+--- mpfr-3.1.3-a/src/mul_ui.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/mul_ui.c 2016-02-15 15:17:39.258577534 +0000
+@@ -126,7 +126,8 @@
+ res = mpfr_mul_ui (y, x, u, rnd_mode);
+ else
+ {
+- res = -mpfr_mul_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
++ res = - mpfr_mul_ui (y, x, - (unsigned long) u,
++ MPFR_INVERT_RND (rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+diff -Naurd mpfr-3.1.3-a/src/si_op.c mpfr-3.1.3-b/src/si_op.c
+--- mpfr-3.1.3-a/src/si_op.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/si_op.c 2016-02-15 15:17:39.258577534 +0000
+@@ -30,7 +30,7 @@
+ if (u >= 0)
+ return mpfr_add_ui (y, x, u, rnd_mode);
+ else
+- return mpfr_sub_ui (y, x, -u, rnd_mode);
++ return mpfr_sub_ui (y, x, - (unsigned long) u, rnd_mode);
+ }
+
+ int
+@@ -39,7 +39,7 @@
+ if (u >= 0)
+ return mpfr_sub_ui (y, x, u, rnd_mode);
+ else
+- return mpfr_add_ui (y, x, -u, rnd_mode);
++ return mpfr_add_ui (y, x, - (unsigned long) u, rnd_mode);
+ }
+
+ int
+@@ -49,9 +49,9 @@
+ return mpfr_ui_sub (y, u, x, rnd_mode);
+ else
+ {
+- int res = -mpfr_add_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
+- MPFR_CHANGE_SIGN (y);
+- return res;
++ int res = - mpfr_add_ui (y, x, - (unsigned long) u,
++ MPFR_INVERT_RND (rnd_mode));
++ MPFR_CHANGE_SIGN (y);
++ return res;
+ }
+ }
+-
+diff -Naurd mpfr-3.1.3-a/src/ui_div.c mpfr-3.1.3-b/src/ui_div.c
+--- mpfr-3.1.3-a/src/ui_div.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/ui_div.c 2016-02-15 15:17:39.258577534 +0000
+@@ -106,7 +106,8 @@
+ res = mpfr_ui_div (y, u, x, rnd_mode);
+ else
+ {
+- res = -mpfr_ui_div (y, -u, x, MPFR_INVERT_RND(rnd_mode));
++ res = - mpfr_ui_div (y, - (unsigned long) u, x,
++ MPFR_INVERT_RND(rnd_mode));
+ MPFR_CHANGE_SIGN (y);
+ }
+ return res;
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:12:59.510314695 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:17:39.282577552 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p8";
++ return "3.1.3-p9";
+ }
diff --git a/patches/mpfr/3.1.3/200-can_round.patch b/patches/mpfr/3.1.3/200-can_round.patch
new file mode 100644
index 0000000..6c0f79a
--- /dev/null
+++ b/patches/mpfr/3.1.3/200-can_round.patch
@@ -0,0 +1,413 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:19:24.210647274 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:19:24.274647313 +0000
+@@ -0,0 +1 @@
++can_round
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:17:39.282577552 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:19:24.274647313 +0000
+@@ -1 +1 @@
+-3.1.3-p9
++3.1.3-p10
+diff -Naurd mpfr-3.1.3-a/src/div.c mpfr-3.1.3-b/src/div.c
+--- mpfr-3.1.3-a/src/div.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/div.c 2016-02-15 15:19:24.250647299 +0000
+@@ -310,24 +310,23 @@
+
+ qp = MPFR_TMP_LIMBS_ALLOC (n);
+ qh = mpfr_divhigh_n (qp, ap, bp, n);
++ MPFR_ASSERTD (qh == 0 || qh == 1);
+ /* in all cases, the error is at most (2n+2) ulps on qh*B^n+{qp,n},
+ cf algorithms.tex */
+
+ p = n * GMP_NUMB_BITS - MPFR_INT_CEIL_LOG2 (2 * n + 2);
+- /* if qh is 1, then we need only PREC(q)-1 bits of {qp,n},
+- if rnd=RNDN, we need to be able to round with a directed rounding
+- and one more bit */
++ /* If rnd=RNDN, we need to be able to round with a directed rounding
++ and one more bit. */
++ if (qh == 1)
++ {
++ mpn_rshift (qp, qp, n, 1);
++ qp[n - 1] |= MPFR_LIMB_HIGHBIT;
++ }
+ if (MPFR_LIKELY (mpfr_round_p (qp, n, p,
+- MPFR_PREC(q) + (rnd_mode == MPFR_RNDN) - qh)))
++ MPFR_PREC(q) + (rnd_mode == MPFR_RNDN))))
+ {
+ /* we can round correctly whatever the rounding mode */
+- if (qh == 0)
+- MPN_COPY (q0p, qp + 1, q0size);
+- else
+- {
+- mpn_rshift (q0p, qp + 1, q0size, 1);
+- q0p[q0size - 1] ^= MPFR_LIMB_HIGHBIT;
+- }
++ MPN_COPY (q0p, qp + 1, q0size);
+ q0p[0] &= ~MPFR_LIMB_MASK(sh); /* put to zero low sh bits */
+
+ if (rnd_mode == MPFR_RNDN) /* round to nearest */
+@@ -335,15 +334,10 @@
+ /* we know we can round, thus we are never in the even rule case:
+ if the round bit is 0, we truncate
+ if the round bit is 1, we add 1 */
+- if (qh == 0)
+- {
+- if (sh > 0)
+- round_bit = (qp[1] >> (sh - 1)) & 1;
+- else
+- round_bit = qp[0] >> (GMP_NUMB_BITS - 1);
+- }
+- else /* qh = 1 */
+- round_bit = (qp[1] >> sh) & 1;
++ if (sh > 0)
++ round_bit = (qp[1] >> (sh - 1)) & 1;
++ else
++ round_bit = qp[0] >> (GMP_NUMB_BITS - 1);
+ if (round_bit == 0)
+ {
+ inex = -1;
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:17:39.282577552 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:19:24.270647311 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p9"
++#define MPFR_VERSION_STRING "3.1.3-p10"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/round_p.c mpfr-3.1.3-b/src/round_p.c
+--- mpfr-3.1.3-a/src/round_p.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/round_p.c 2016-02-15 15:19:24.250647299 +0000
+@@ -31,7 +31,11 @@
+ {
+ int i1, i2;
+
++ MPFR_ASSERTN(bp[bn - 1] & MPFR_LIMB_HIGHBIT);
++
+ i1 = mpfr_round_p_2 (bp, bn, err0, prec);
++
++ /* compare with mpfr_can_round_raw */
+ i2 = mpfr_can_round_raw (bp, bn, MPFR_SIGN_POS, err0,
+ MPFR_RNDN, MPFR_RNDZ, prec);
+ if (i1 != i2)
+@@ -42,6 +46,7 @@
+ gmp_fprintf (stderr, "%NX\n", bp, bn);
+ MPFR_ASSERTN (0);
+ }
++
+ return i1;
+ }
+ # define mpfr_round_p mpfr_round_p_2
+@@ -62,6 +67,8 @@
+ mp_limb_t tmp, mask;
+ int s;
+
++ MPFR_ASSERTD(bp[bn - 1] & MPFR_LIMB_HIGHBIT);
++
+ err = (mpfr_prec_t) bn * GMP_NUMB_BITS;
+ if (MPFR_UNLIKELY (err0 <= 0 || (mpfr_uexp_t) err0 <= prec || prec >= err))
+ return 0; /* can't round */
+diff -Naurd mpfr-3.1.3-a/src/round_prec.c mpfr-3.1.3-b/src/round_prec.c
+--- mpfr-3.1.3-a/src/round_prec.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/round_prec.c 2016-02-15 15:19:24.250647299 +0000
+@@ -141,24 +141,40 @@
+ mpfr_can_round_raw (const mp_limb_t *bp, mp_size_t bn, int neg, mpfr_exp_t err0,
+ mpfr_rnd_t rnd1, mpfr_rnd_t rnd2, mpfr_prec_t prec)
+ {
+- mpfr_prec_t err;
++ mpfr_prec_t err, prec0 = prec;
+ mp_size_t k, k1, tn;
+ int s, s1;
+ mp_limb_t cc, cc2;
+ mp_limb_t *tmp;
+ MPFR_TMP_DECL(marker);
+
++ MPFR_ASSERTD(bp[bn - 1] & MPFR_LIMB_HIGHBIT);
++
+ if (MPFR_UNLIKELY(err0 < 0 || (mpfr_uexp_t) err0 <= prec))
+ return 0; /* can't round */
+- else if (MPFR_UNLIKELY (prec > (mpfr_prec_t) bn * GMP_NUMB_BITS))
+- { /* then ulp(b) < precision < error */
+- return rnd2 == MPFR_RNDN && (mpfr_uexp_t) err0 - 2 >= prec;
+- /* can round only in rounding to the nearest and err0 >= prec + 2 */
+- }
+
+ MPFR_ASSERT_SIGN(neg);
+ neg = MPFR_IS_NEG_SIGN(neg);
+
++ /* Transform RNDD and RNDU to Zero / Away */
++ 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;
++
++ 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
++ (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. */
++ if (rnd2 == MPFR_RNDN)
++ return (mpfr_uexp_t) err0 - 2 >= prec;
++ else
++ return (rnd1 == rnd2) && (mpfr_uexp_t) err0 - 2 >= prec;
++ }
++
+ /* 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) ?
+@@ -168,19 +184,25 @@
+ k = (err - 1) / GMP_NUMB_BITS;
+ MPFR_UNSIGNED_MINUS_MODULO(s, err);
+ /* the error corresponds to bit s in limb k, the most significant limb
+- being limb 0 */
++ being limb 0; in memory, limb k is bp[bn-1-k]. */
+
+ k1 = (prec - 1) / GMP_NUMB_BITS;
+ MPFR_UNSIGNED_MINUS_MODULO(s1, prec);
+- /* the last significant bit is bit s1 in limb k1 */
++ /* the least significant bit is bit s1 in limb k1 */
+
+- /* don't need to consider the k1 most significant limbs */
++ /* We don't need to consider the k1 most significant limbs.
++ They will be considered later only to detect when subtracting
++ the error bound yields a change of binade.
++ Warning! The number with updated bn may no longer be normalized. */
+ k -= k1;
+ bn -= k1;
+ prec -= (mpfr_prec_t) k1 * GMP_NUMB_BITS;
+
+- /* if when adding or subtracting (1 << s) in bp[bn-1-k], it does not
+- change bp[bn-1] >> s1, then we can round */
++ /* 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
++ adding or subtracting (1 << s) in bp[bn-1-k], it does not change the
++ rounding in direction 'rnd2' at ulp-position bp[bn-1] >> s1, taking also
++ into account the possible change of binade. */
+ MPFR_TMP_MARK(marker);
+ tn = bn;
+ k++; /* since we work with k+1 everywhere */
+@@ -190,11 +212,6 @@
+
+ MPFR_ASSERTD (k > 0);
+
+- /* Transform RNDD and RNDU to Zero / Away */
+- MPFR_ASSERTD((neg == 0) || (neg ==1));
+- if (MPFR_IS_RNDUTEST_OR_RNDDNOTTEST(rnd1, neg))
+- rnd1 = MPFR_RNDZ;
+-
+ switch (rnd1)
+ {
+ case MPFR_RNDZ:
+@@ -203,33 +220,54 @@
+ /* 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 is the new value of bit s1 in bp[bn-1] */
++ /* cc is the new value of bit s1 in bp[bn-1] after rounding 'rnd2' */
++
+ /* now round b + 2^(MPFR_EXP(b)-err) */
+- cc2 = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
++ 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 */
+ break;
+ case MPFR_RNDN:
+ /* Round to nearest */
+- /* first round b+2^(MPFR_EXP(b)-err) */
+- cc = mpn_add_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
++
++ /* 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() */
+ cc = (tmp[bn - 1] >> s1) & 1; /* gives 0 when cc=1 */
+ cc ^= mpfr_round_raw2 (tmp, bn, neg, rnd2, prec);
++ /* cc is the new value of bit s1 in bp[bn-1]+eps after rounding 'rnd2' */
++
++ 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);
++ /* 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.
++ */
++ 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))
++ {
++ MPFR_TMP_FREE(marker);
++ return 0;
++ }
+ break;
+ default:
+ /* Round away */
+ cc = (bp[bn - 1] >> s1) & 1;
+ cc ^= mpfr_round_raw2 (bp, bn, neg, rnd2, prec);
+- /* now round b +/- 2^(MPFR_EXP(b)-err) */
+- cc2 = mpn_sub_1 (tmp + bn - k, bp + bn - k, k, MPFR_LIMB_ONE << s);
+- break;
+- }
++ /* cc is the new value of bit s1 in bp[bn-1]+eps after rounding 'rnd2' */
+
+- /* if cc2 is 1, then a carry or borrow propagates to the next limb */
+- if (cc2 && cc)
+- {
+- MPFR_TMP_FREE(marker);
+- return 0;
++ goto subtract_eps;
+ }
+
+ cc2 = (tmp[bn - 1] >> s1) & 1;
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:17:39.282577552 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:19:24.274647313 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p9";
++ return "3.1.3-p10";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tcan_round.c mpfr-3.1.3-b/tests/tcan_round.c
+--- mpfr-3.1.3-a/tests/tcan_round.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tcan_round.c 2016-02-15 15:19:24.250647299 +0000
+@@ -1,4 +1,4 @@
+-/* Test file for mpfr_can_round.
++/* Test file for mpfr_can_round and mpfr_round_p.
+
+ Copyright 1999, 2001-2015 Free Software Foundation, Inc.
+ Contributed by the AriC and Caramel projects, INRIA.
+@@ -41,6 +41,8 @@
+ /* avoid mpn_random which leaks memory */
+ for (i = 0; i < n; i++)
+ buf[i] = randlimb ();
++ /* force the number to be normalized */
++ buf[n - 1] |= MPFR_LIMB_HIGHBIT;
+ p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
+ err = p + randlimb () % GMP_NUMB_BITS;
+ r1 = mpfr_round_p (buf, n, err, p);
+@@ -57,11 +59,72 @@
+ }
+ }
+
++/* check x=2^i with precision px, error at most 1, and target precision prec */
++static void
++test_pow2 (mpfr_exp_t i, mpfr_prec_t px, mpfr_rnd_t r1, mpfr_rnd_t r2,
++ mpfr_prec_t prec)
++{
++ mpfr_t x;
++ int b, expected_b, b2;
++
++ mpfr_init2 (x, px);
++ mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
++ b = !!mpfr_can_round (x, i+1, r1, r2, prec);
++ /* Note: If mpfr_can_round succeeds for both
++ (r1,r2) = (MPFR_RNDD,MPFR_RNDN) and
++ (r1,r2) = (MPFR_RNDU,MPFR_RNDN), then it should succeed for
++ (r1,r2) = (MPFR_RNDN,MPFR_RNDN). So, the condition on prec below
++ for r1 = MPFR_RNDN should be the most restrictive between those
++ for r1 = any directed rounding mode.
++ For r1 like MPFR_RNDA, the unrounded, unknown number may be anyone
++ in [2^i-1,i]. As both 2^i-1 and 2^i fit on i bits, one cannot round
++ in any precision >= i bits, hence the condition prec < i; prec = i-1
++ will work here for r2 = MPFR_RNDN thanks to the even-rounding rule
++ (and also with rounding ties away from zero). */
++ expected_b =
++ MPFR_IS_LIKE_RNDD (r1, MPFR_SIGN_POS) ?
++ (MPFR_IS_LIKE_RNDU (r2, MPFR_SIGN_POS) ? 0 : prec <= i) :
++ 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)
++ {
++ 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,
++ mpfr_print_rnd_mode (r1), mpfr_print_rnd_mode (r2), (int) prec);
++ printf ("Expected %d, got %d\n", expected_b, b);
++ exit (1);
++ }
++
++ if (r1 == MPFR_RNDN && r2 == MPFR_RNDZ)
++ {
++ /* Similar test to the one done in src/round_p.c
++ for MPFR_WANT_ASSERT >= 2. */
++ b2 = !!mpfr_round_p (MPFR_MANT(x), MPFR_LIMB_SIZE(x), i+1, prec);
++ if (b2 != b)
++ {
++ printf ("Error for x=2^%d, px=%lu, err=%d, prec=%d\n",
++ (int) i, (unsigned long) px, (int) i + 1, (int) prec);
++ printf ("mpfr_can_round gave %d, mpfr_round_p gave %d\n", b, b2);
++ exit (1);
++ }
++ }
++
++ mpfr_clear (x);
++}
++
+ int
+ main (void)
+ {
+ mpfr_t x;
+- mpfr_prec_t i, j;
++ mpfr_prec_t i, j, k;
++ int r1, r2;
++ int n;
+
+ tests_start_mpfr ();
+
+@@ -111,12 +174,30 @@
+ mpfr_set_str (x, "0.ff4ca619c76ba69", 16, MPFR_RNDZ);
+ for (i = 30; i < 99; i++)
+ for (j = 30; j < 99; j++)
+- {
+- int r1, r2;
+- for (r1 = 0; r1 < MPFR_RND_MAX ; r1++)
+- for (r2 = 0; r2 < MPFR_RND_MAX ; r2++)
+- mpfr_can_round (x, i, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j); /* test for assertions */
+- }
++ for (r1 = 0; r1 < MPFR_RND_MAX; r1++)
++ for (r2 = 0; r2 < MPFR_RND_MAX; r2++)
++ {
++ /* test for assertions */
++ mpfr_can_round (x, i, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j);
++ }
++
++ test_pow2 (32, 32, MPFR_RNDN, MPFR_RNDN, 32);
++ test_pow2 (174, 174, MPFR_RNDN, MPFR_RNDN, 174);
++ test_pow2 (174, 174, MPFR_RNDU, MPFR_RNDN, 174);
++ test_pow2 (176, 129, MPFR_RNDU, MPFR_RNDU, 174);
++ test_pow2 (176, 2, MPFR_RNDZ, MPFR_RNDZ, 174);
++ test_pow2 (176, 2, MPFR_RNDU, MPFR_RNDU, 176);
++
++ /* Tests for x = 2^i (E(x) = i+1) with error at most 1 = 2^0. */
++ for (n = 0; n < 100; n++)
++ {
++ i = (randlimb() % 200) + 4;
++ for (j = i - 2; j < i + 2; j++)
++ for (r1 = 0; r1 < MPFR_RND_MAX; r1++)
++ for (r2 = 0; r2 < MPFR_RND_MAX; r2++)
++ for (k = MPFR_PREC_MIN; k <= i + 2; k++)
++ test_pow2 (i, k, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j);
++ }
+
+ mpfr_clear (x);
+
diff --git a/patches/mpfr/3.1.3/210-fits.patch b/patches/mpfr/3.1.3/210-fits.patch
new file mode 100644
index 0000000..888389c
--- /dev/null
+++ b/patches/mpfr/3.1.3/210-fits.patch
@@ -0,0 +1,584 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:20:16.854677843 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:20:16.922677881 +0000
+@@ -0,0 +1 @@
++fits
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:19:24.274647313 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:20:16.922677881 +0000
+@@ -1 +1 @@
+-3.1.3-p10
++3.1.3-p11
+diff -Naurd mpfr-3.1.3-a/src/fits_intmax.c mpfr-3.1.3-b/src/fits_intmax.c
+--- mpfr-3.1.3-a/src/fits_intmax.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/fits_intmax.c 2016-02-15 15:20:16.898677867 +0000
+@@ -33,6 +33,7 @@
+ int
+ mpfr_fits_intmax_p (mpfr_srcptr f, mpfr_rnd_t rnd)
+ {
++ unsigned int saved_flags;
+ mpfr_exp_t e;
+ int prec;
+ mpfr_t x, y;
+@@ -85,6 +86,7 @@
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
++ saved_flags = __gmpfr_flags;
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+
+@@ -97,10 +99,16 @@
+ }
+ else
+ {
+- res = MPFR_GET_EXP (x) == e;
++ /* Warning! Due to the rounding, x can be an infinity. Here we use
++ the fact that singular numbers have a special exponent field,
++ thus well-defined and different from e, in which case this means
++ that the number does not fit. That's why we use MPFR_EXP, not
++ MPFR_GET_EXP. */
++ res = MPFR_EXP (x) == e;
+ }
+
+ mpfr_clear (x);
++ __gmpfr_flags = saved_flags;
+ return res;
+ }
+
+diff -Naurd mpfr-3.1.3-a/src/fits_s.h mpfr-3.1.3-b/src/fits_s.h
+--- mpfr-3.1.3-a/src/fits_s.h 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/fits_s.h 2016-02-15 15:20:16.898677867 +0000
+@@ -29,6 +29,7 @@
+ int
+ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
+ {
++ unsigned int saved_flags;
+ mpfr_exp_t e;
+ int prec;
+ mpfr_t x;
+@@ -81,9 +82,16 @@
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
++ saved_flags = __gmpfr_flags;
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+- res = neg ? (mpfr_cmp_si (x, MINIMUM) >= 0) : (MPFR_GET_EXP (x) == e);
++ /* Warning! Due to the rounding, x can be an infinity. Here we use
++ the fact that singular numbers have a special exponent field,
++ thus well-defined and different from e, in which case this means
++ that the number does not fit. That's why we use MPFR_EXP, not
++ MPFR_GET_EXP. */
++ res = neg ? (mpfr_cmp_si (x, MINIMUM) >= 0) : (MPFR_EXP (x) == e);
+ mpfr_clear (x);
++ __gmpfr_flags = saved_flags;
+ return res;
+ }
+diff -Naurd mpfr-3.1.3-a/src/fits_u.h mpfr-3.1.3-b/src/fits_u.h
+--- mpfr-3.1.3-a/src/fits_u.h 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/fits_u.h 2016-02-15 15:20:16.898677867 +0000
+@@ -25,6 +25,7 @@
+ int
+ FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd)
+ {
++ unsigned int saved_flags;
+ mpfr_exp_t e;
+ int prec;
+ TYPE s;
+@@ -62,9 +63,16 @@
+ MPFR_ASSERTD (e == prec);
+
+ /* hard case: first round to prec bits, then check */
++ saved_flags = __gmpfr_flags;
+ mpfr_init2 (x, prec);
+ mpfr_set (x, f, rnd);
+- res = MPFR_GET_EXP (x) == e;
++ /* Warning! Due to the rounding, x can be an infinity. Here we use
++ the fact that singular numbers have a special exponent field,
++ thus well-defined and different from e, in which case this means
++ that the number does not fit. That's why we use MPFR_EXP, not
++ MPFR_GET_EXP. */
++ res = MPFR_EXP (x) == e;
+ mpfr_clear (x);
++ __gmpfr_flags = saved_flags;
+ return res;
+ }
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:19:24.270647311 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:20:16.922677881 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p10"
++#define MPFR_VERSION_STRING "3.1.3-p11"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:19:24.274647313 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:20:16.922677881 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p10";
++ return "3.1.3-p11";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tfits.c mpfr-3.1.3-b/tests/tfits.c
+--- mpfr-3.1.3-a/tests/tfits.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tfits.c 2016-02-15 15:20:16.898677867 +0000
+@@ -33,258 +33,225 @@
+ #include "mpfr-intmax.h"
+ #include "mpfr-test.h"
+
+-#define ERROR1(N) \
++#define FTEST_AUX(N,NOT,FCT) \
+ do \
+ { \
+- printf("Error %d for rnd = %s and x = ", N, \
+- mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \
+- mpfr_dump(x); \
+- exit(1); \
++ __gmpfr_flags = ex_flags; \
++ if (NOT FCT (x, (mpfr_rnd_t) r)) \
++ { \
++ printf ("Error %d for %s, rnd = %s and x = ", \
++ N, #FCT, \
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \
++ mpfr_dump (x); \
++ exit (1); \
++ } \
++ if (__gmpfr_flags != ex_flags) \
++ { \
++ unsigned int flags = __gmpfr_flags; \
++ printf ("Flags error %d for %s, rnd = %s and x = ", \
++ N, #FCT, \
++ mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \
++ mpfr_dump(x); \
++ printf ("Expected flags:"); \
++ flags_out (ex_flags); \
++ printf ("Got flags: "); \
++ flags_out (flags); \
++ exit (1); \
++ } \
+ } \
+ while (0)
+
+-static void check_intmax (void);
++#define FTEST(N,NOT,FCT) \
++ do \
++ { \
++ mpfr_exp_t e; \
++ FTEST_AUX (N,NOT,FCT); \
++ if (MPFR_IS_SINGULAR (x)) \
++ break; \
++ e = mpfr_get_exp (x); \
++ set_emin (e); \
++ set_emax (e); \
++ FTEST_AUX (N,NOT,FCT); \
++ set_emin (emin); \
++ set_emax (emax); \
++ } \
++ while (0)
++
++#define CHECK_ALL(N,NOT) \
++ do \
++ { \
++ FTEST (N, NOT, mpfr_fits_ulong_p); \
++ FTEST (N, NOT, mpfr_fits_slong_p); \
++ FTEST (N, NOT, mpfr_fits_uint_p); \
++ FTEST (N, NOT, mpfr_fits_sint_p); \
++ FTEST (N, NOT, mpfr_fits_ushort_p); \
++ FTEST (N, NOT, mpfr_fits_sshort_p); \
++ } \
++ while (0)
++
++#define CHECK_MAX(N,NOT) \
++ do \
++ { \
++ FTEST (N, NOT, mpfr_fits_uintmax_p); \
++ FTEST (N, NOT, mpfr_fits_intmax_p); \
++ } \
++ while (0)
++
++/* V is a non-zero limit for the type (*_MIN for a signed type or *_MAX).
++ * If V is positive, then test V, V + 1/4, V + 3/4 and V + 1.
++ * If V is negative, then test V, V - 1/4, V - 3/4 and V - 1.
++ */
++#define CHECK_LIM(N,V,SET,FCT) \
++ do \
++ { \
++ SET (x, V, MPFR_RNDN); \
++ FTEST (N, !, FCT); \
++ mpfr_set_si_2exp (y, (V) < 0 ? -1 : 1, -2, MPFR_RNDN); \
++ mpfr_add (x, x, y, MPFR_RNDN); \
++ FTEST (N+1, (r == MPFR_RNDN || \
++ MPFR_IS_LIKE_RNDZ (r, (V) < 0)) ^ !!, FCT); \
++ mpfr_add (x, x, y, MPFR_RNDN); \
++ mpfr_add (x, x, y, MPFR_RNDN); \
++ FTEST (N+3, MPFR_IS_LIKE_RNDZ (r, (V) < 0) ^ !!, FCT); \
++ mpfr_add (x, x, y, MPFR_RNDN); \
++ FTEST (N+4, !!, FCT); \
++ } \
++ while (0)
+
+ int
+ main (void)
+ {
++ mpfr_exp_t emin, emax;
+ mpfr_t x, y;
+- int i, r;
++ unsigned int flags[2] = { 0, MPFR_FLAGS_ALL }, ex_flags;
++ int i, r, fi;
+
+ tests_start_mpfr ();
+
+- mpfr_init2 (x, 256);
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++
++ mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 2);
+ mpfr_init2 (y, 8);
+
+ RND_LOOP (r)
+- {
+-
+- /* Check NAN */
+- mpfr_set_nan (x);
+- if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (1);
+- if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (2);
+- if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (3);
+- if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (4);
+- if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (5);
+- if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (6);
++ for (fi = 0; fi < numberof (flags); fi++)
++ {
++ ex_flags = flags[fi];
+
+- /* Check INF */
+- mpfr_set_inf (x, 1);
+- if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (7);
+- if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (8);
+- if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (9);
+- if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (10);
+- if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (11);
+- if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (12);
++ /* Check NaN */
++ mpfr_set_nan (x);
++ CHECK_ALL (1, !!);
+
+- /* Check Zero */
+- MPFR_SET_ZERO (x);
+- if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (13);
+- if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (14);
+- if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (15);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (16);
+- if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (17);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (18);
++ /* Check +Inf */
++ mpfr_set_inf (x, 1);
++ CHECK_ALL (2, !!);
+
+- /* Check small positive op */
+- mpfr_set_str1 (x, "1@-1");
+- if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (19);
+- if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (20);
+- if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (21);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (22);
+- if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (23);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (24);
++ /* Check -Inf */
++ mpfr_set_inf (x, -1);
++ CHECK_ALL (3, !!);
+
+- /* Check 17 */
+- mpfr_set_ui (x, 17, MPFR_RNDN);
+- if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (25);
+- if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (26);
+- if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (27);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (28);
+- if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (29);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (30);
++ /* Check +0 */
++ mpfr_set_zero (x, 1);
++ CHECK_ALL (4, !);
+
+- /* Check all other values */
+- mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+- mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (31);
+- if (mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (32);
+- mpfr_mul_2exp (x, x, 40, MPFR_RNDN);
+- if (mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (33);
+- if (mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (34);
+- if (mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (35);
+- if (mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (36);
+- if (mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (37);
++ /* Check -0 */
++ mpfr_set_zero (x, -1);
++ CHECK_ALL (5, !);
+
+- mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
+- if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (38);
+- mpfr_set_ui (x, LONG_MAX, MPFR_RNDN);
+- if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (39);
+- mpfr_set_ui (x, UINT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (40);
+- mpfr_set_ui (x, INT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (41);
+- mpfr_set_ui (x, USHRT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (42);
+- mpfr_set_ui (x, SHRT_MAX, MPFR_RNDN);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (43);
++ /* Check small positive op */
++ mpfr_set_str1 (x, "1@-1");
++ CHECK_ALL (6, !);
+
+- mpfr_set_si (x, 1, MPFR_RNDN);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (44);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (45);
++ /* Check 17 */
++ mpfr_set_ui (x, 17, MPFR_RNDN);
++ CHECK_ALL (7, !);
+
+- /* Check negative op */
+- for (i = 1; i <= 4; i++)
+- {
+- int inv;
++ /* Check large values (no fit) */
++ mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
++ mpfr_mul_2exp (x, x, 1, MPFR_RNDN);
++ CHECK_ALL (8, !!);
++ mpfr_mul_2exp (x, x, 40, MPFR_RNDN);
++ CHECK_ALL (9, !!);
+
+- mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
+- mpfr_rint (y, x, (mpfr_rnd_t) r);
+- inv = MPFR_NOTZERO (y);
+- if (!mpfr_fits_ulong_p (x, (mpfr_rnd_t) r) ^ inv)
+- ERROR1 (46);
+- if (!mpfr_fits_slong_p (x, (mpfr_rnd_t) r))
+- ERROR1 (47);
+- if (!mpfr_fits_uint_p (x, (mpfr_rnd_t) r) ^ inv)
+- ERROR1 (48);
+- if (!mpfr_fits_sint_p (x, (mpfr_rnd_t) r))
+- ERROR1 (49);
+- if (!mpfr_fits_ushort_p (x, (mpfr_rnd_t) r) ^ inv)
+- ERROR1 (50);
+- if (!mpfr_fits_sshort_p (x, (mpfr_rnd_t) r))
+- ERROR1 (51);
+- }
+- }
++ /* Check a non-integer number just below a power of two. */
++ mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
++ CHECK_ALL (10, !);
+
+- mpfr_clear (x);
+- mpfr_clear (y);
++ /* Check the limits of the types (except 0 for unsigned types) */
++ CHECK_LIM (20, ULONG_MAX, mpfr_set_ui, mpfr_fits_ulong_p);
++ CHECK_LIM (30, LONG_MAX, mpfr_set_si, mpfr_fits_slong_p);
++ CHECK_LIM (35, LONG_MIN, mpfr_set_si, mpfr_fits_slong_p);
++ CHECK_LIM (40, UINT_MAX, mpfr_set_ui, mpfr_fits_uint_p);
++ CHECK_LIM (50, INT_MAX, mpfr_set_si, mpfr_fits_sint_p);
++ CHECK_LIM (55, INT_MIN, mpfr_set_si, mpfr_fits_sint_p);
++ CHECK_LIM (60, USHRT_MAX, mpfr_set_ui, mpfr_fits_ushort_p);
++ CHECK_LIM (70, SHRT_MAX, mpfr_set_si, mpfr_fits_sshort_p);
++ CHECK_LIM (75, SHRT_MIN, mpfr_set_si, mpfr_fits_sshort_p);
+
+- check_intmax ();
++ /* Check negative op */
++ for (i = 1; i <= 4; i++)
++ {
++ int inv;
+
+- tests_end_mpfr ();
+- return 0;
+-}
++ mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
++ mpfr_rint (y, x, (mpfr_rnd_t) r);
++ inv = MPFR_NOTZERO (y);
++ FTEST (80, inv ^ !, mpfr_fits_ulong_p);
++ FTEST (81, !, mpfr_fits_slong_p);
++ FTEST (82, inv ^ !, mpfr_fits_uint_p);
++ FTEST (83, !, mpfr_fits_sint_p);
++ FTEST (84, inv ^ !, mpfr_fits_ushort_p);
++ FTEST (85, !, mpfr_fits_sshort_p);
++ }
++ }
+
+-static void
+-check_intmax (void)
+-{
+ #ifdef _MPFR_H_HAVE_INTMAX_T
+- mpfr_t x, y;
+- int i, r;
+
+- mpfr_init2 (x, sizeof (uintmax_t) * CHAR_BIT);
+- mpfr_init2 (y, 8);
++ mpfr_set_prec (x, sizeof (uintmax_t) * CHAR_BIT + 2);
+
+ RND_LOOP (r)
+ {
+- /* Check NAN */
++ /* Check NaN */
+ mpfr_set_nan (x);
+- if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (52);
+- if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (53);
++ CHECK_MAX (1, !!);
+
+- /* Check INF */
++ /* Check +Inf */
+ mpfr_set_inf (x, 1);
+- if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (54);
+- if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (55);
++ CHECK_MAX (2, !!);
+
+- /* Check Zero */
+- MPFR_SET_ZERO (x);
+- if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (56);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (57);
++ /* Check -Inf */
++ mpfr_set_inf (x, -1);
++ CHECK_MAX (3, !!);
+
+- /* Check positive small op */
++ /* Check +0 */
++ mpfr_set_zero (x, 1);
++ CHECK_MAX (4, !);
++
++ /* Check -0 */
++ mpfr_set_zero (x, -1);
++ CHECK_MAX (5, !);
++
++ /* Check small positive op */
+ mpfr_set_str1 (x, "1@-1");
+- if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (58);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (59);
++ CHECK_MAX (6, !);
+
+ /* Check 17 */
+ mpfr_set_ui (x, 17, MPFR_RNDN);
+- if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (60);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (61);
++ CHECK_MAX (7, !);
+
+ /* Check hugest */
+ mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
+- if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (62);
+- if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (63);
++ CHECK_MAX (8, !!);
+
+- /* Check all other values */
+- mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+- mpfr_add_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (64);
+- mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
+- if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (65);
+- mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+- mpfr_add_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (66);
+- mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (67);
+- mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (68);
+- mpfr_sub_ui (x, x, 1, MPFR_RNDN);
+- if (mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (69);
++ /* Check a non-integer number just below a power of two. */
++ mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
++ CHECK_MAX (10, !);
++
++ /* Check the limits of the types (except 0 for uintmax_t) */
++ CHECK_LIM (20, MPFR_UINTMAX_MAX, mpfr_set_uj, mpfr_fits_uintmax_p);
++ CHECK_LIM (30, MPFR_INTMAX_MAX, mpfr_set_sj, mpfr_fits_intmax_p);
++ CHECK_LIM (35, MPFR_INTMAX_MIN, mpfr_set_sj, mpfr_fits_intmax_p);
+
+ /* Check negative op */
+ for (i = 1; i <= 4; i++)
+@@ -294,14 +261,16 @@
+ mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
+ mpfr_rint (y, x, (mpfr_rnd_t) r);
+ inv = MPFR_NOTZERO (y);
+- if (!mpfr_fits_uintmax_p (x, (mpfr_rnd_t) r) ^ inv)
+- ERROR1 (70);
+- if (!mpfr_fits_intmax_p (x, (mpfr_rnd_t) r))
+- ERROR1 (71);
++ FTEST (80, inv ^ !, mpfr_fits_uintmax_p);
++ FTEST (81, !, mpfr_fits_intmax_p);
+ }
+ }
+
++#endif /* _MPFR_H_HAVE_INTMAX_T */
++
+ mpfr_clear (x);
+ mpfr_clear (y);
+-#endif
++
++ tests_end_mpfr ();
++ return 0;
+ }
diff --git a/patches/mpfr/3.1.3/220-root.patch b/patches/mpfr/3.1.3/220-root.patch
new file mode 100644
index 0000000..9cd62a7
--- /dev/null
+++ b/patches/mpfr/3.1.3/220-root.patch
@@ -0,0 +1,621 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-15 15:20:51.242696408 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-15 15:20:51.306696441 +0000
+@@ -0,0 +1 @@
++root
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:20:16.922677881 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-15 15:20:51.306696441 +0000
+@@ -1 +1 @@
+-3.1.3-p11
++3.1.3-p12
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:20:16.922677881 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-15 15:20:51.302696439 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p11"
++#define MPFR_VERSION_STRING "3.1.3-p12"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/root.c mpfr-3.1.3-b/src/root.c
+--- mpfr-3.1.3-a/src/root.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/root.c 2016-02-15 15:20:51.282696429 +0000
+@@ -23,13 +23,15 @@
+ #define MPFR_NEED_LONGLONG_H
+ #include "mpfr-impl.h"
+
+- /* The computation of y = x^(1/k) is done as follows:
++ /* The computation of y = x^(1/k) is done as follows, except for large
++ values of k, for which this would be inefficient or yield internal
++ integer overflows:
+
+ Let x = sign * m * 2^(k*e) where m is an integer
+
+ with 2^(k*(n-1)) <= m < 2^(k*n) where n = PREC(y)
+
+- and m = s^k + r where 0 <= r and m < (s+1)^k
++ and m = s^k + t where 0 <= t and m < (s+1)^k
+
+ we want that s has n bits i.e. s >= 2^(n-1), or m >= 2^(k*(n-1))
+ i.e. m must have at least k*(n-1)+1 bits
+@@ -38,11 +40,15 @@
+ x^(1/k) = s * 2^e or (s+1) * 2^e according to the rounding mode.
+ */
+
++static int
++mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k,
++ mpfr_rnd_t rnd_mode);
++
+ int
+ mpfr_root (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
+ {
+ mpz_t m;
+- mpfr_exp_t e, r, sh;
++ mpfr_exp_t e, r, sh, f;
+ mpfr_prec_t n, size_m, tmp;
+ int inexact, negative;
+ MPFR_SAVE_EXPO_DECL (expo);
+@@ -55,50 +61,27 @@
+
+ if (MPFR_UNLIKELY (k <= 1))
+ {
+- if (k < 1) /* k==0 => y=x^(1/0)=x^(+Inf) */
+-#if 0
+- /* For 0 <= x < 1 => +0.
+- For x = 1 => 1.
+- For x > 1, => +Inf.
+- For x < 0 => NaN.
+- */
++ if (k == 0)
+ {
+- if (MPFR_IS_NEG (x) && !MPFR_IS_ZERO (x))
+- {
+- MPFR_SET_NAN (y);
+- MPFR_RET_NAN;
+- }
+- inexact = mpfr_cmp (x, __gmpfr_one);
+- if (inexact == 0)
+- return mpfr_set_ui (y, 1, rnd_mode); /* 1 may be Out of Range */
+- else if (inexact < 0)
+- return mpfr_set_ui (y, 0, rnd_mode); /* 0+ */
+- else
+- {
+- mpfr_set_inf (y, 1);
+- return 0;
+- }
++ MPFR_SET_NAN (y);
++ MPFR_RET_NAN;
+ }
+-#endif
+- {
+- MPFR_SET_NAN (y);
+- MPFR_RET_NAN;
+- }
+- else /* y =x^(1/1)=x */
++ else /* y = x^(1/1) = x */
+ return mpfr_set (y, x, rnd_mode);
+ }
+
+ /* Singular values */
+- else if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
++ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
+ {
+ if (MPFR_IS_NAN (x))
+ {
+ MPFR_SET_NAN (y); /* NaN^(1/k) = NaN */
+ MPFR_RET_NAN;
+ }
+- else if (MPFR_IS_INF (x)) /* +Inf^(1/k) = +Inf
+- -Inf^(1/k) = -Inf if k odd
+- -Inf^(1/k) = NaN if k even */
++
++ if (MPFR_IS_INF (x)) /* +Inf^(1/k) = +Inf
++ -Inf^(1/k) = -Inf if k odd
++ -Inf^(1/k) = NaN if k even */
+ {
+ if (MPFR_IS_NEG(x) && (k % 2 == 0))
+ {
+@@ -106,27 +89,31 @@
+ MPFR_RET_NAN;
+ }
+ MPFR_SET_INF (y);
+- MPFR_SET_SAME_SIGN (y, x);
+- MPFR_RET (0);
+ }
+ else /* x is necessarily 0: (+0)^(1/k) = +0
+ (-0)^(1/k) = -0 */
+ {
+ MPFR_ASSERTD (MPFR_IS_ZERO (x));
+ MPFR_SET_ZERO (y);
+- MPFR_SET_SAME_SIGN (y, x);
+- MPFR_RET (0);
+ }
++ MPFR_SET_SAME_SIGN (y, x);
++ MPFR_RET (0);
+ }
+
+ /* Returns NAN for x < 0 and k even */
+- else if (MPFR_IS_NEG (x) && (k % 2 == 0))
++ if (MPFR_UNLIKELY (MPFR_IS_NEG (x) && (k % 2 == 0)))
+ {
+ MPFR_SET_NAN (y);
+ MPFR_RET_NAN;
+ }
+
+ /* General case */
++
++ /* For large k, use exp(log(x)/k). The threshold of 100 seems to be quite
++ good when the precision goes to infinity. */
++ if (k > 100)
++ return mpfr_root_aux (y, x, k, rnd_mode);
++
+ MPFR_SAVE_EXPO_MARK (expo);
+ mpz_init (m);
+
+@@ -135,31 +122,24 @@
+ mpz_neg (m, m);
+ r = e % (mpfr_exp_t) k;
+ if (r < 0)
+- r += k; /* now r = e (mod k) with 0 <= e < r */
++ r += k; /* now r = e (mod k) with 0 <= r < k */
++ MPFR_ASSERTD (0 <= r && r < k);
+ /* x = (m*2^r) * 2^(e-r) where e-r is a multiple of k */
+
+ MPFR_MPZ_SIZEINBASE2 (size_m, m);
+ /* for rounding to nearest, we want the round bit to be in the root */
+ n = MPFR_PREC (y) + (rnd_mode == MPFR_RNDN);
+
+- /* we now multiply m by 2^(r+k*sh) so that root(m,k) will give
+- exactly n bits: we want k*(n-1)+1 <= size_m + k*sh + r <= k*n
+- i.e. sh = floor ((kn-size_m-r)/k) */
+- if ((mpfr_exp_t) size_m + r > k * (mpfr_exp_t) n)
+- sh = 0; /* we already have too many bits */
++ /* we now multiply m by 2^sh so that root(m,k) will give
++ exactly n bits: we want k*(n-1)+1 <= size_m + sh <= k*n
++ i.e. sh = k*f + r with f = max(floor((k*n-size_m-r)/k),0) */
++ if ((mpfr_exp_t) size_m + r >= k * (mpfr_exp_t) n)
++ f = 0; /* we already have too many bits */
+ else
+- sh = (k * (mpfr_exp_t) n - (mpfr_exp_t) size_m - r) / k;
+- sh = k * sh + r;
+- if (sh >= 0)
+- {
+- mpz_mul_2exp (m, m, sh);
+- e = e - sh;
+- }
+- else if (r > 0)
+- {
+- mpz_mul_2exp (m, m, r);
+- e = e - r;
+- }
++ f = (k * (mpfr_exp_t) n - (mpfr_exp_t) size_m - r) / k;
++ sh = k * f + r;
++ mpz_mul_2exp (m, m, sh);
++ e = e - sh;
+
+ /* invariant: x = m*2^e, with e divisible by k */
+
+@@ -203,3 +183,97 @@
+ MPFR_SAVE_EXPO_FREE (expo);
+ return mpfr_check_range (y, inexact, rnd_mode);
+ }
++
++/* Compute y <- x^(1/k) using exp(log(x)/k).
++ Assume all special cases have been eliminated before.
++ In the extended exponent range, overflows/underflows are not possible.
++ Assume x > 0, or x < 0 and k odd.
++*/
++static int
++mpfr_root_aux (mpfr_ptr y, mpfr_srcptr x, unsigned long k, mpfr_rnd_t rnd_mode)
++{
++ int inexact, exact_root = 0;
++ mpfr_prec_t w; /* working precision */
++ mpfr_t absx, t;
++ MPFR_GROUP_DECL(group);
++ MPFR_TMP_DECL(marker);
++ MPFR_ZIV_DECL(loop);
++ MPFR_SAVE_EXPO_DECL (expo);
++
++ MPFR_TMP_INIT_ABS (absx, x);
++
++ MPFR_TMP_MARK(marker);
++ w = MPFR_PREC(y) + 10;
++ /* Take some guard bits to prepare for the 'expt' lost bits below.
++ If |x| < 2^k, then log|x| < k, thus taking log2(k) bits should be fine. */
++ if (MPFR_GET_EXP(x) > 0)
++ w += MPFR_INT_CEIL_LOG2 (MPFR_GET_EXP(x));
++ MPFR_GROUP_INIT_1(group, w, t);
++ MPFR_SAVE_EXPO_MARK (expo);
++ MPFR_ZIV_INIT (loop, w);
++ for (;;)
++ {
++ mpfr_exp_t expt;
++ unsigned int err;
++
++ mpfr_log (t, absx, MPFR_RNDN);
++ /* t = log|x| * (1 + theta) with |theta| <= 2^(-w) */
++ mpfr_div_ui (t, t, k, MPFR_RNDN);
++ expt = MPFR_GET_EXP (t);
++ /* t = log|x|/k * (1 + theta) + eps with |theta| <= 2^(-w)
++ and |eps| <= 1/2 ulp(t), thus the total error is bounded
++ by 1.5 * 2^(expt - w) */
++ mpfr_exp (t, t, MPFR_RNDN);
++ /* t = |x|^(1/k) * exp(tau) * (1 + theta1) with
++ |tau| <= 1.5 * 2^(expt - w) and |theta1| <= 2^(-w).
++ For |tau| <= 0.5 we have |exp(tau)-1| < 4/3*tau, thus
++ for w >= expt + 2 we have:
++ t = |x|^(1/k) * (1 + 2^(expt+2)*theta2) * (1 + theta1) with
++ |theta1|, |theta2| <= 2^(-w).
++ If expt+2 > 0, as long as w >= 1, we have:
++ t = |x|^(1/k) * (1 + 2^(expt+3)*theta3) with |theta3| < 2^(-w).
++ For expt+2 = 0, we have:
++ t = |x|^(1/k) * (1 + 2^2*theta3) with |theta3| < 2^(-w).
++ Finally for expt+2 < 0 we have:
++ t = |x|^(1/k) * (1 + 2*theta3) with |theta3| < 2^(-w).
++ */
++ err = (expt + 2 > 0) ? expt + 3
++ : (expt + 2 == 0) ? 2 : 1;
++ /* now t = |x|^(1/k) * (1 + 2^(err-w)) thus the error is at most
++ 2^(EXP(t) - w + err) */
++ if (MPFR_LIKELY (MPFR_CAN_ROUND(t, w - err, MPFR_PREC(y), rnd_mode)))
++ break;
++
++ /* If we fail to round correctly, check for an exact result or a
++ midpoint result with MPFR_RNDN (regarded as hard-to-round in
++ all precisions in order to determine the ternary value). */
++ {
++ mpfr_t z, zk;
++
++ mpfr_init2 (z, MPFR_PREC(y) + (rnd_mode == MPFR_RNDN));
++ mpfr_init2 (zk, MPFR_PREC(x));
++ mpfr_set (z, t, MPFR_RNDN);
++ inexact = mpfr_pow_ui (zk, z, k, MPFR_RNDN);
++ exact_root = !inexact && mpfr_equal_p (zk, absx);
++ if (exact_root) /* z is the exact root, thus round z directly */
++ inexact = mpfr_set4 (y, z, rnd_mode, MPFR_SIGN (x));
++ mpfr_clear (zk);
++ mpfr_clear (z);
++ if (exact_root)
++ break;
++ }
++
++ MPFR_ZIV_NEXT (loop, w);
++ MPFR_GROUP_REPREC_1(group, w, t);
++ }
++ MPFR_ZIV_FREE (loop);
++
++ if (!exact_root)
++ inexact = mpfr_set4 (y, t, rnd_mode, MPFR_SIGN (x));
++
++ MPFR_GROUP_CLEAR(group);
++ MPFR_TMP_FREE(marker);
++ MPFR_SAVE_EXPO_FREE (expo);
++
++ return mpfr_check_range (y, inexact, rnd_mode);
++}
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:20:16.922677881 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-15 15:20:51.306696441 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p11";
++ return "3.1.3-p12";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/troot.c mpfr-3.1.3-b/tests/troot.c
+--- mpfr-3.1.3-a/tests/troot.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/troot.c 2016-02-15 15:20:51.282696429 +0000
+@@ -25,6 +25,19 @@
+
+ #include "mpfr-test.h"
+
++#define DEFN(N) \
++ static int root##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
++ { return mpfr_root (y, x, N, rnd); } \
++ static int pow##N (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) \
++ { return mpfr_pow_ui (y, x, N, rnd); }
++
++DEFN(2)
++DEFN(3)
++DEFN(4)
++DEFN(5)
++DEFN(17)
++DEFN(120)
++
+ static void
+ special (void)
+ {
+@@ -52,7 +65,7 @@
+ exit (1);
+ }
+
+- /* root(-Inf, 17) = -Inf */
++ /* root(-Inf, 17) = -Inf */
+ mpfr_set_inf (x, -1);
+ mpfr_root (y, x, 17, MPFR_RNDN);
+ if (!mpfr_inf_p (y) || mpfr_sgn (y) > 0)
+@@ -69,7 +82,7 @@
+ exit (1);
+ }
+
+- /* root(+/-0) = +/-0 */
++ /* root(+/-0, k) = +/-0 for k > 0 */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ mpfr_root (y, x, 17, MPFR_RNDN);
+ if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
+@@ -190,64 +203,39 @@
+ i = mpfr_root (y, x, 1, MPFR_RNDN);
+ if (mpfr_cmp_ui (x, 17) || i != 0)
+ {
+- printf ("Error in root (17^(1/1))\n");
++ printf ("Error in root for 17^(1/1)\n");
+ exit (1);
+ }
+
+-#if 0
+- /* Check for k == 0:
+- For 0 <= x < 1 => +0.
+- For x = 1 => 1.
+- For x > 1, => +Inf.
+- For x < 0 => NaN. */
+- i = mpfr_root (y, x, 0, MPFR_RNDN);
+- if (!MPFR_IS_INF (y) || !MPFR_IS_POS (y) || i != 0)
+- {
+- printf ("Error in root 17^(1/0)\n");
+- exit (1);
+- }
+- mpfr_set_ui (x, 1, MPFR_RNDN);
+- i = mpfr_root (y, x, 0, MPFR_RNDN);
+- if (mpfr_cmp_ui (y, 1) || i != 0)
+- {
+- printf ("Error in root 1^(1/0)\n");
+- exit (1);
+- }
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+- if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
+- {
+- printf ("Error in root 0+^(1/0)\n");
+- exit (1);
+- }
+- MPFR_CHANGE_SIGN (x);
+- i = mpfr_root (y, x, 0, MPFR_RNDN);
+- if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
++ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+- printf ("Error in root 0-^(1/0)\n");
++ printf ("Error in root for (+0)^(1/0)\n");
+ exit (1);
+ }
+- mpfr_set_ui_2exp (x, 17, -5, MPFR_RNDD);
++ mpfr_neg (x, x, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+- if (!MPFR_IS_ZERO (y) || !MPFR_IS_POS (y) || i != 0)
++ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+- printf ("Error in root (17/2^5)^(1/0)\n");
++ printf ("Error in root for (-0)^(1/0)\n");
+ exit (1);
+ }
+-#endif
+- mpfr_set_ui (x, 0, MPFR_RNDN);
++
++ mpfr_set_ui (x, 1, MPFR_RNDN);
+ i = mpfr_root (y, x, 0, MPFR_RNDN);
+ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+- printf ("Error in root 0+^(1/0)\n");
++ printf ("Error in root for 1^(1/0)\n");
+ exit (1);
+ }
++
+ /* Check for k==2 */
+ mpfr_set_si (x, -17, MPFR_RNDD);
+ i = mpfr_root (y, x, 2, MPFR_RNDN);
+ if (!MPFR_IS_NAN (y) || i != 0)
+ {
+- printf ("Error in root (-17)^(1/2)\n");
++ printf ("Error in root for (-17)^(1/2)\n");
+ exit (1);
+ }
+
+@@ -255,11 +243,168 @@
+ mpfr_clear (y);
+ }
+
++/* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=812779
++ * https://bugzilla.gnome.org/show_bug.cgi?id=756960
++ * is a GNOME Calculator bug (mpfr_root applied on a negative integer,
++ * which is converted to an unsigned integer), but the strange result
++ * is also due to a bug in MPFR.
++ */
++static void
++bigint (void)
++{
++ mpfr_t x, y;
++
++ mpfr_inits2 (64, x, y, (mpfr_ptr) 0);
++
++ mpfr_set_ui (x, 10, MPFR_RNDN);
++ if (sizeof (unsigned long) * CHAR_BIT == 64)
++ {
++ mpfr_root (x, x, ULONG_MAX, MPFR_RNDN);
++ mpfr_set_ui_2exp (y, 1, -63, MPFR_RNDN);
++ mpfr_add_ui (y, y, 1, MPFR_RNDN);
++ if (! mpfr_equal_p (x, y))
++ {
++ printf ("Error in bigint for ULONG_MAX\n");
++ printf ("Expected ");
++ mpfr_dump (y);
++ printf ("Got ");
++ mpfr_dump (x);
++ exit (1);
++ }
++ }
++
++ mpfr_set_ui (x, 10, MPFR_RNDN);
++ mpfr_root (x, x, 1234567890, MPFR_RNDN);
++ mpfr_set_str_binary (y,
++ "1.00000000000000000000000000001000000000101011000101000110010001");
++ if (! mpfr_equal_p (x, y))
++ {
++ printf ("Error in bigint for 1234567890\n");
++ printf ("Expected ");
++ mpfr_dump (y);
++ printf ("Got ");
++ mpfr_dump (x);
++ exit (1);
++ }
++
++ mpfr_clears (x, y, (mpfr_ptr) 0);
++}
++
+ #define TEST_FUNCTION mpfr_root
+ #define INTEGER_TYPE unsigned long
+-#define INT_RAND_FUNCTION() (INTEGER_TYPE) (randlimb () % 3 +2)
++#define INT_RAND_FUNCTION() \
++ (INTEGER_TYPE) (randlimb () & 1 ? randlimb () : randlimb () % 3 + 2)
+ #include "tgeneric_ui.c"
+
++static void
++exact_powers (unsigned long bmax, unsigned long kmax)
++{
++ long b, k;
++ mpz_t z;
++ mpfr_t x, y;
++ int inex, neg;
++
++ mpz_init (z);
++ for (b = 2; b <= bmax; b++)
++ for (k = 1; k <= kmax; k++)
++ {
++ mpz_ui_pow_ui (z, b, k);
++ mpfr_init2 (x, mpz_sizeinbase (z, 2));
++ mpfr_set_ui (x, b, MPFR_RNDN);
++ mpfr_pow_ui (x, x, k, MPFR_RNDN);
++ mpz_set_ui (z, b);
++ mpfr_init2 (y, mpz_sizeinbase (z, 2));
++ for (neg = 0; neg <= 1; neg++)
++ {
++ inex = mpfr_root (y, x, k, MPFR_RNDN);
++ if (inex != 0)
++ {
++ printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k);
++ printf ("Expected inex=0, got %d\n", inex);
++ exit (1);
++ }
++ if (neg && (k & 1) == 0)
++ {
++ if (!MPFR_IS_NAN (y))
++ {
++ printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k);
++ printf ("Expected y=NaN\n");
++ printf ("Got ");
++ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++ }
++ else if (MPFR_IS_NAN (y) || mpfr_cmp_si (y, b) != 0)
++ {
++ printf ("Error in exact_powers, b=%ld, k=%ld\n", b, k);
++ printf ("Expected y=%ld\n", b);
++ printf ("Got ");
++ mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
++ printf ("\n");
++ exit (1);
++ }
++ mpfr_neg (x, x, MPFR_RNDN);
++ b = -b;
++ }
++ mpfr_clear (x);
++ mpfr_clear (y);
++ }
++ mpz_clear (z);
++}
++
++/* Compare root(x,2^h) with pow(x,2^(-h)). */
++static void
++cmp_pow (void)
++{
++ mpfr_t x, y1, y2;
++ int h;
++
++ mpfr_inits2 (128, x, y1, y2, (mpfr_ptr) 0);
++
++ for (h = 1; h < sizeof (unsigned long) * CHAR_BIT; h++)
++ {
++ unsigned long k = (unsigned long) 1 << h;
++ int i;
++
++ for (i = 0; i < 10; i++)
++ {
++ mpfr_rnd_t rnd;
++ unsigned int flags1, flags2;
++ int inex1, inex2;
++
++ tests_default_random (x, 0, __gmpfr_emin, __gmpfr_emax, 1);
++ rnd = RND_RAND ();
++ mpfr_set_ui_2exp (y1, 1, -h, MPFR_RNDN);
++ mpfr_clear_flags ();
++ inex1 = mpfr_pow (y1, x, y1, rnd);
++ flags1 = __gmpfr_flags;
++ mpfr_clear_flags ();
++ inex2 = mpfr_root (y2, x, k, rnd);
++ flags2 = __gmpfr_flags;
++ if (!(mpfr_equal_p (y1, y2) && SAME_SIGN (inex1, inex2) &&
++ flags1 == flags2))
++ {
++ printf ("Error in cmp_pow on h=%d, i=%d, rnd=%s\n",
++ h, i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
++ printf ("x = ");
++ mpfr_dump (x);
++ printf ("pow = ");
++ mpfr_dump (y1);
++ printf ("with inex = %d, flags =", inex1);
++ flags_out (flags1);
++ printf ("root = ");
++ mpfr_dump (y2);
++ printf ("with inex = %d, flags =", inex2);
++ flags_out (flags2);
++ exit (1);
++ }
++ }
++ }
++
++ mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
++}
++
+ int
+ main (void)
+ {
+@@ -270,7 +415,10 @@
+
+ tests_start_mpfr ();
+
++ exact_powers (3, 1000);
+ special ();
++ bigint ();
++ cmp_pow ();
+
+ mpfr_init (x);
+
+@@ -329,6 +477,13 @@
+
+ test_generic_ui (2, 200, 30);
+
++ bad_cases (root2, pow2, "mpfr_root[2]", 8, -256, 255, 4, 128, 800, 40);
++ bad_cases (root3, pow3, "mpfr_root[3]", 8, -256, 255, 4, 128, 800, 40);
++ bad_cases (root4, pow4, "mpfr_root[4]", 8, -256, 255, 4, 128, 800, 40);
++ bad_cases (root5, pow5, "mpfr_root[5]", 8, -256, 255, 4, 128, 800, 40);
++ bad_cases (root17, pow17, "mpfr_root[17]", 8, -256, 255, 4, 128, 800, 40);
++ bad_cases (root120, pow120, "mpfr_root[120]", 8, -256, 255, 4, 128, 800, 40);
++
+ tests_end_mpfr ();
+ return 0;
+ }
diff --git a/patches/mpfr/3.1.3/230-gamma.patch b/patches/mpfr/3.1.3/230-gamma.patch
new file mode 100644
index 0000000..47d4e41
--- /dev/null
+++ b/patches/mpfr/3.1.3/230-gamma.patch
@@ -0,0 +1,77 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-23 07:43:23.702095604 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-23 07:43:23.726095285 +0000
+@@ -0,0 +1 @@
++gamma
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-15 15:20:51.306696441 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-23 07:43:23.726095285 +0000
+@@ -1 +1 @@
+-3.1.3-p12
++3.1.3-p13
+diff -Naurd mpfr-3.1.3-a/src/gamma.c mpfr-3.1.3-b/src/gamma.c
+--- mpfr-3.1.3-a/src/gamma.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/gamma.c 2016-02-23 07:43:23.718095391 +0000
+@@ -70,6 +70,9 @@
+ {
+ mpfr_t x, y;
+ unsigned long r, k;
++ MPFR_SAVE_EXPO_DECL (expo);
++
++ MPFR_SAVE_EXPO_MARK (expo);
+ mpfr_init2 (x, 38);
+ mpfr_init2 (y, 38);
+ mpfr_set_ui (x, n, MPFR_RNDZ);
+@@ -86,6 +89,8 @@
+ r -= n / k;
+ mpfr_clear (x);
+ mpfr_clear (y);
++ MPFR_SAVE_EXPO_FREE (expo);
++
+ return r;
+ }
+
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-15 15:20:51.302696439 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 07:43:23.726095285 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p12"
++#define MPFR_VERSION_STRING "3.1.3-p13"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-15 15:20:51.306696441 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-23 07:43:23.726095285 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p12";
++ return "3.1.3-p13";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tgamma.c mpfr-3.1.3-b/tests/tgamma.c
+--- mpfr-3.1.3-a/tests/tgamma.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tgamma.c 2016-02-23 07:43:23.718095391 +0000
+@@ -192,6 +192,18 @@
+ exit (1);
+ }
+
++ mpfr_set_prec (x, 2);
++ mpfr_set_prec (y, 2);
++ mpfr_set_ui (x, 2, MPFR_RNDN);
++ mpfr_clear_inexflag ();
++ mpfr_gamma (y, x, MPFR_RNDN);
++ if (mpfr_inexflag_p ())
++ {
++ printf ("Wrong inexact flag for gamma(2)\n");
++ printf ("expected 0, got 1\n");
++ exit (1);
++ }
++
+ mpfr_clear (x);
+ mpfr_clear (y);
+ }
diff --git a/patches/mpfr/3.1.3/240-rem1.patch b/patches/mpfr/3.1.3/240-rem1.patch
new file mode 100644
index 0000000..9d5e3c1
--- /dev/null
+++ b/patches/mpfr/3.1.3/240-rem1.patch
@@ -0,0 +1,337 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-23 07:54:06.617533218 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-23 07:54:06.641532898 +0000
+@@ -0,0 +1 @@
++rem1
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-23 07:43:23.726095285 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-23 07:54:06.641532898 +0000
+@@ -1 +1 @@
+-3.1.3-p13
++3.1.3-p14
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-23 07:43:23.726095285 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 07:54:06.641532898 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p13"
++#define MPFR_VERSION_STRING "3.1.3-p14"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/rem1.c mpfr-3.1.3-b/src/rem1.c
+--- mpfr-3.1.3-a/src/rem1.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/rem1.c 2016-02-23 07:54:06.633533004 +0000
+@@ -59,6 +59,7 @@
+ mpfr_exp_t ex, ey;
+ int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
+ mpz_t mx, my, r;
++ int tiny = 0;
+
+ MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);
+
+@@ -109,13 +110,27 @@
+ if (ex <= ey)
+ {
+ /* q = x/y = mx/(my*2^(ey-ex)) */
+- mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */
+- if (rnd_q == MPFR_RNDZ)
+- /* 0 <= |r| <= |my|, r has the same sign as mx */
+- mpz_tdiv_qr (mx, r, mx, my);
++
++ /* First detect cases where q=0, to avoid creating a huge number
++ my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy =
++ mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and
++ y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1
++ the quotient is 0 */
++ if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) <
++ ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
++ {
++ tiny = 1;
++ mpz_set (r, mx);
++ mpz_set_ui (mx, 0);
++ }
+ else
+- /* 0 <= |r| <= |my|, r has the same sign as my */
+- mpz_fdiv_qr (mx, r, mx, my);
++ {
++ mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */
++
++ /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */
++ mpz_tdiv_qr (mx, r, mx, my);
++ /* 0 <= |r| <= |my|, r has the same sign as mx */
++ }
+
+ if (rnd_q == MPFR_RNDN)
+ q_is_odd = mpz_tstbit (mx, 0);
+@@ -181,7 +196,20 @@
+ /* FIXME: the comparison 2*r < my could be done more efficiently
+ at the mpn level */
+ mpz_mul_2exp (r, r, 1);
+- compare = mpz_cmpabs (r, my);
++ /* if tiny=1, we should compare r with my*2^(ey-ex) */
++ if (tiny)
++ {
++ if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) <
++ ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
++ compare = 0; /* r*2^ex < my*2^ey */
++ else
++ {
++ mpz_mul_2exp (my, my, ey - ex);
++ compare = mpz_cmpabs (r, my);
++ }
++ }
++ else
++ compare = mpz_cmpabs (r, my);
+ mpz_fdiv_q_2exp (r, r, 1);
+ compare = ((compare > 0) ||
+ ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-23 07:43:23.726095285 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-23 07:54:06.641532898 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p13";
++ return "3.1.3-p14";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tfmod.c mpfr-3.1.3-b/tests/tfmod.c
+--- mpfr-3.1.3-a/tests/tfmod.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tfmod.c 2016-02-23 07:54:06.633533004 +0000
+@@ -137,89 +137,90 @@
+ special (void)
+ {
+ int inexact;
+- mpfr_t x, y, r, nan;
+- mpfr_inits (x, y, r, nan, (mpfr_ptr) 0);
++ mpfr_t x, y, r, t;
+
+- mpfr_set_nan (nan);
++ mpfr_inits (x, y, r, t, (mpfr_ptr) 0);
++
++ mpfr_set_nan (t);
+
+ /* fmod (NaN, NaN) is NaN */
+ mpfr_set_nan (x);
+ mpfr_set_nan (y);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (NaN, +0) is NaN */
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+1, 0) is NaN */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (0, 0) is NaN */
+ mpfr_set_ui (x, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +0) is NaN */
+ mpfr_set_inf (x, +1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +0) is NaN */
+ mpfr_set_inf (x, -1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, -0) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +1) is NaN */
+ mpfr_set_ui (y, +1, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +1) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, -inf) is NaN */
+ mpfr_set_inf (y, -1);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, -inf) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (-inf, +inf) is NaN */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+inf, +inf) is NaN */
+ mpfr_neg (x, x, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (x, +inf) = x, if x is finite */
+ mpfr_set_ui (x, 1, MPFR_RNDN);
+@@ -271,13 +272,13 @@
+ mpfr_set_ui (y, 0, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, -0) is NaN */
+ mpfr_neg (y, y, MPFR_RNDN);
+ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
+ if (!mpfr_nan_p (r) || inexact != 0)
+- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN);
++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN);
+
+ /* fmod (+0, +1) = +0 */
+ mpfr_set_ui (y, 1, MPFR_RNDN);
+@@ -303,7 +304,18 @@
+ if (!mpfr_equal_p (r, x) || inexact != 0)
+ test_failed (r, x, 0, inexact, x, y, MPFR_RNDN);
+
+- mpfr_clears (x, y, r, nan, (mpfr_ptr) 0);
++ mpfr_set_prec (x, 380);
++ mpfr_set_prec (y, 385);
++ mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E0");
++ mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1");
++ mpfr_set_prec (r, 2);
++ inexact = mpfr_fmod (r, x, y, MPFR_RNDA);
++ mpfr_set_prec (t, 2);
++ mpfr_set_ui_2exp (t, 3, -5, MPFR_RNDN);
++ if (mpfr_cmp_ui_2exp (r, 3, -5) || inexact <= 0)
++ test_failed (r, t, 1, inexact, x, y, MPFR_RNDA);
++
++ mpfr_clears (x, y, r, t, (mpfr_ptr) 0);
+ return;
+ }
+
+@@ -313,6 +325,7 @@
+ {
+ mpfr_t x, y, r;
+ int inexact;
++
+ mpfr_inits2 (100, x, y, r, (mpfr_ptr) 0);
+
+ mpfr_set_prec (x, 3);
+@@ -353,7 +366,46 @@
+ mpfr_sin (y, y, MPFR_RNDN);
+ check (r, x, y, MPFR_RNDN);
+
+- mpfr_clears(r, x, y, (mpfr_ptr) 0);
++ mpfr_clears (x, y, r, (mpfr_ptr) 0);
++}
++
++static void
++bug20160217 (void)
++{
++ mpfr_t x, y, r;
++ int inexact, i;
++ mpfr_exp_t emin, emax;
++
++ mpfr_inits2 (53, x, y, r, (mpfr_ptr) 0);
++
++ emin = mpfr_get_emin ();
++ emax = mpfr_get_emax ();
++
++ for (i = 0; i <= 1; i++)
++ {
++ mpfr_set_zero (x, 1);
++ mpfr_nextabove (x);
++ mpfr_set_inf (y, 1);
++ mpfr_nextbelow (y);
++ inexact = mpfr_fmod (r, x, y, MPFR_RNDN);
++ if (!mpfr_equal_p (r, x) || inexact != 0)
++ {
++ printf ("Error for mpfr_fmod (r, nextabove(0), nextbelow(+inf),"
++ " MPFR_RNDN)%s\n", i ? "extended exponent range" : "");
++ printf ("Expected inex = 0, r = ");
++ mpfr_dump (x);
++ printf ("Got inex = %d, r = ", inexact);
++ mpfr_dump (r);
++ exit (1);
++ }
++ set_emin (MPFR_EMIN_MIN);
++ set_emax (MPFR_EMAX_MAX);
++ }
++
++ set_emin (emin);
++ set_emax (emax);
++
++ mpfr_clears (x, y, r, (mpfr_ptr) 0);
+ }
+
+ int
+@@ -362,6 +414,7 @@
+ tests_start_mpfr ();
+
+ bug20090519 ();
++ bug20160217 ();
+
+ test_generic (2, 100, 100);
+
+diff -Naurd mpfr-3.1.3-a/tests/tremquo.c mpfr-3.1.3-b/tests/tremquo.c
+--- mpfr-3.1.3-a/tests/tremquo.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tremquo.c 2016-02-23 07:54:06.633533004 +0000
+@@ -59,6 +59,7 @@
+ {
+ mpfr_t x, y, r;
+ long q[1];
++ int inex;
+
+ if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */
+ {
+@@ -281,6 +282,15 @@
+ MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0);
+ MPFR_ASSERTN (q[0] == 0);
+
++ mpfr_set_prec (x, 380);
++ mpfr_set_prec (y, 385);
++ mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E-2");
++ mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1");
++ mpfr_set_prec (r, 2);
++ inex = mpfr_remainder (r, x, y, MPFR_RNDA);
++ MPFR_ASSERTN(mpfr_cmp_si_2exp (r, -3, -4) == 0);
++ MPFR_ASSERTN(inex < 0);
++
+ mpfr_clear (x);
+ mpfr_clear (y);
+ mpfr_clear (r);
diff --git a/patches/mpfr/3.1.3/250-agm-eq.patch b/patches/mpfr/3.1.3/250-agm-eq.patch
new file mode 100644
index 0000000..e59e914
--- /dev/null
+++ b/patches/mpfr/3.1.3/250-agm-eq.patch
@@ -0,0 +1,105 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-23 07:55:17.208593082 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-23 07:55:17.232592762 +0000
+@@ -0,0 +1 @@
++agm-eq
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-23 07:54:06.641532898 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-23 07:55:17.232592762 +0000
+@@ -1 +1 @@
+-3.1.3-p14
++3.1.3-p15
+diff -Naurd mpfr-3.1.3-a/src/agm.c mpfr-3.1.3-b/src/agm.c
+--- mpfr-3.1.3-a/src/agm.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/agm.c 2016-02-23 07:55:17.224592868 +0000
+@@ -96,10 +96,7 @@
+ /* b (op2) and a (op1) are the 2 operands but we want b >= a */
+ compare = mpfr_cmp (op1, op2);
+ if (MPFR_UNLIKELY( compare == 0 ))
+- {
+- mpfr_set (r, op1, rnd_mode);
+- MPFR_RET (0); /* exact */
+- }
++ return mpfr_set (r, op1, rnd_mode);
+ else if (compare > 0)
+ {
+ mpfr_srcptr t = op1;
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-23 07:54:06.641532898 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 07:55:17.232592762 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p14"
++#define MPFR_VERSION_STRING "3.1.3-p15"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-23 07:54:06.641532898 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-23 07:55:17.232592762 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p14";
++ return "3.1.3-p15";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tagm.c mpfr-3.1.3-b/tests/tagm.c
+--- mpfr-3.1.3-a/tests/tagm.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tagm.c 2016-02-23 07:55:17.224592868 +0000
+@@ -169,6 +169,45 @@
+ }
+
+ static void
++check_eq (void)
++{
++ mpfr_t a, b, agm;
++ int p;
++
++ mpfr_init2 (a, 17);
++ mpfr_init2 (b, 9);
++
++ mpfr_set_str_binary (b, "0.101000000E-3");
++ mpfr_set (a, b, MPFR_RNDN);
++
++ for (p = MPFR_PREC_MIN; p <= 2; p++)
++ {
++ int inex;
++
++ mpfr_init2 (agm, p);
++ inex = mpfr_agm (agm, a, b, MPFR_RNDU);
++ if (mpfr_cmp_ui_2exp (agm, 5 - p, -5) != 0)
++ {
++ printf ("Error in check_eq for p = %d: expected %d*2^(-5), got ",
++ p, 5 - p);
++ mpfr_dump (agm);
++ exit (1);
++ }
++ if (inex <= 0)
++ {
++ printf ("Wrong ternary value in check_eq for p = %d\n", p);
++ printf ("expected 1\n");
++ printf ("got %d\n", inex);
++ exit (1);
++ }
++ mpfr_clear (agm);
++ }
++
++ mpfr_clear (a);
++ mpfr_clear (b);
++}
++
++static void
+ check_nans (void)
+ {
+ mpfr_t x, y, m;
+@@ -260,6 +299,7 @@
+ check_nans ();
+
+ check_large ();
++ check_eq ();
+ check4 ("2.0", "1.0", MPFR_RNDN, "1.456791031046906869", -1);
+ check4 ("6.0", "4.0", MPFR_RNDN, "4.949360872472608925", 1);
+ check4 ("62.0", "61.0", MPFR_RNDN, "61.498983718845075902", -1);
diff --git a/patches/mpfr/3.1.3/260-sum.patch b/patches/mpfr/3.1.3/260-sum.patch
new file mode 100644
index 0000000..6fae047
--- /dev/null
+++ b/patches/mpfr/3.1.3/260-sum.patch
@@ -0,0 +1,223 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-23 07:55:54.028346753 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-23 07:55:54.052346433 +0000
+@@ -0,0 +1 @@
++sum
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-23 07:55:17.232592762 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-23 07:55:54.052346433 +0000
+@@ -1 +1 @@
+-3.1.3-p15
++3.1.3-p16
+diff -Naurd mpfr-3.1.3-a/src/mpfr-impl.h mpfr-3.1.3-b/src/mpfr-impl.h
+--- mpfr-3.1.3-a/src/mpfr-impl.h 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/mpfr-impl.h 2016-02-23 07:55:54.040346593 +0000
+@@ -1876,7 +1876,8 @@
+ __MPFR_DECLSPEC int mpfr_check _MPFR_PROTO ((mpfr_srcptr));
+
+ __MPFR_DECLSPEC int mpfr_sum_sort _MPFR_PROTO ((mpfr_srcptr *const,
+- unsigned long, mpfr_srcptr *));
++ unsigned long, mpfr_srcptr *,
++ mpfr_prec_t *));
+
+ __MPFR_DECLSPEC int mpfr_get_cputime _MPFR_PROTO ((void));
+
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-23 07:55:17.232592762 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 07:55:54.052346433 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p15"
++#define MPFR_VERSION_STRING "3.1.3-p16"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/sum.c mpfr-3.1.3-b/src/sum.c
+--- mpfr-3.1.3-a/src/sum.c 2015-06-19 19:55:09.000000000 +0000
++++ mpfr-3.1.3-b/src/sum.c 2016-02-23 07:55:54.040346593 +0000
+@@ -45,9 +45,13 @@
+ mpfr_exp_t, mpfr_uexp_t);
+
+ /* Either sort the tab in perm and returns 0
+- Or returns 1 for +INF, -1 for -INF and 2 for NAN */
++ Or returns 1 for +INF, -1 for -INF and 2 for NAN.
++ Also set *maxprec to the maximal precision of tab[0..n-1] and of the
++ initial value of *maxprec.
++*/
+ int
+-mpfr_sum_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm)
++mpfr_sum_sort (mpfr_srcptr *const tab, unsigned long n, mpfr_srcptr *perm,
++ mpfr_prec_t *maxprec)
+ {
+ mpfr_exp_t min, max;
+ mpfr_uexp_t exp_num;
+@@ -79,6 +83,8 @@
+ if (MPFR_GET_EXP (tab[i]) > max)
+ max = MPFR_GET_EXP(tab[i]);
+ }
++ if (MPFR_PREC (tab[i]) > *maxprec)
++ *maxprec = MPFR_PREC (tab[i]);
+ }
+ if (MPFR_UNLIKELY (sign_inf != 0))
+ return sign_inf;
+@@ -213,7 +219,8 @@
+
+
+ /* Sum a list of float with order given by permutation perm,
+- * intermediate size set to F.
++ * intermediate size set to F. Return non-zero if at least one of
++ * the operations is inexact (thus 0 implies that the sum is exact).
+ * Internal use function.
+ */
+ static int
+@@ -230,16 +237,19 @@
+ for (i = 1; i < n - 1; i++)
+ {
+ MPFR_ASSERTD (!MPFR_IS_NAN (sum) && !MPFR_IS_INF (sum));
+- error_trap |= mpfr_add (sum, sum, tab[i], MPFR_RNDN);
++ if (mpfr_add (sum, sum, tab[i], MPFR_RNDN))
++ error_trap = 1;
+ }
+- error_trap |= mpfr_add (ret, sum, tab[n - 1], MPFR_RNDN);
++ if (mpfr_add (ret, sum, tab[n - 1], MPFR_RNDN))
++ error_trap = 1;
+ mpfr_clear (sum);
+ return error_trap;
+ }
+
+ /* Sum a list of floating-point numbers.
++ * If the return value is 0, then the sum is exact.
++ * Otherwise the return value gives no information.
+ */
+-
+ int
+ mpfr_sum (mpfr_ptr ret, mpfr_ptr *const tab_p, unsigned long n, mpfr_rnd_t rnd)
+ {
+@@ -266,7 +276,8 @@
+ /* Sort and treat special cases */
+ MPFR_TMP_MARK (marker);
+ perm = (mpfr_srcptr *) MPFR_TMP_ALLOC (n * sizeof *perm);
+- error_trap = mpfr_sum_sort (tab, n, perm);
++ prec = MPFR_PREC (ret);
++ error_trap = mpfr_sum_sort (tab, n, perm, &prec);
+ /* Check if there was a NAN or a INF */
+ if (MPFR_UNLIKELY (error_trap != 0))
+ {
+@@ -281,8 +292,7 @@
+ MPFR_RET (0);
+ }
+
+- /* Initial precision */
+- prec = MAX (MPFR_PREC (tab[0]), MPFR_PREC (ret));
++ /* Initial precision is max(prec(ret),prec(tab[0]),...,prec(tab[n-1])) */
+ k = MPFR_INT_CEIL_LOG2 (n) + 1;
+ prec += k + 2;
+ mpfr_init2 (cur_sum, prec);
+@@ -295,8 +305,7 @@
+ error_trap = sum_once (cur_sum, perm, n, prec + k);
+ if (MPFR_LIKELY (error_trap == 0 ||
+ (!MPFR_IS_ZERO (cur_sum) &&
+- mpfr_can_round (cur_sum,
+- MPFR_GET_EXP (cur_sum) - prec + 2,
++ mpfr_can_round (cur_sum, prec - 2,
+ MPFR_RNDN, rnd, MPFR_PREC (ret)))))
+ break;
+ MPFR_ZIV_NEXT (loop, prec);
+@@ -305,11 +314,13 @@
+ MPFR_ZIV_FREE (loop);
+ MPFR_TMP_FREE (marker);
+
+- error_trap |= mpfr_set (ret, cur_sum, rnd);
++ if (mpfr_set (ret, cur_sum, rnd))
++ error_trap = 1;
+ mpfr_clear (cur_sum);
+
+ MPFR_SAVE_EXPO_FREE (expo);
+- error_trap |= mpfr_check_range (ret, 0, rnd);
++ if (mpfr_check_range (ret, 0, rnd))
++ error_trap = 1;
+ return error_trap; /* It doesn't return the ternary value */
+ }
+
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-23 07:55:17.232592762 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-23 07:55:54.052346433 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p15";
++ return "3.1.3-p16";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tsum.c mpfr-3.1.3-b/tests/tsum.c
+--- mpfr-3.1.3-a/tests/tsum.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tsum.c 2016-02-23 07:55:54.040346593 +0000
+@@ -126,6 +126,7 @@
+ mpfr_ptr *tabtmp;
+ mpfr_srcptr *perm;
+ unsigned long i;
++ mpfr_prec_t prec = MPFR_PREC_MIN;
+
+ /* Init stuff */
+ tab = (mpfr_t *) (*__gmp_allocate_func) (n * sizeof (mpfr_t));
+@@ -140,7 +141,7 @@
+ tabtmp[i] = tab[i];
+ }
+
+- mpfr_sum_sort ((mpfr_srcptr *)tabtmp, n, perm);
++ mpfr_sum_sort ((mpfr_srcptr *)tabtmp, n, perm, &prec);
+
+ if (check_is_sorted (n, perm) == 0)
+ {
+@@ -300,6 +301,41 @@
+ mpfr_clears (tab[0], tab[1], tab[2], r, (mpfr_ptr) 0);
+ }
+
++/* bug reported by Joseph S. Myers on 2013-10-27
++ https://sympa.inria.fr/sympa/arc/mpfr/2013-10/msg00015.html */
++static void
++bug20131027 (void)
++{
++ mpfr_t r, t[4];
++ mpfr_ptr p[4];
++ char *s[4] = {
++ "0x1p1000",
++ "-0x0.fffffffffffff80000000000000001p1000",
++ "-0x1p947",
++ "0x1p880"
++ };
++ int i;
++
++ mpfr_init2 (r, 53);
++ for (i = 0; i < 4; i++)
++ {
++ mpfr_init2 (t[i], i == 0 ? 53 : 1000);
++ mpfr_set_str (t[i], s[i], 0, MPFR_RNDN);
++ p[i] = t[i];
++ }
++ mpfr_sum (r, p, 4, MPFR_RNDN);
++
++ if (MPFR_NOTZERO (r))
++ {
++ printf ("mpfr_sum incorrect in bug20131027: expected 0, got\n");
++ mpfr_dump (r);
++ exit (1);
++ }
++
++ for (i = 0; i < 4; i++)
++ mpfr_clear (t[i]);
++ mpfr_clear (r);
++}
+
+ int
+ main (void)
+@@ -310,6 +346,7 @@
+ tests_start_mpfr ();
+
+ check_special ();
++ bug20131027 ();
+ test_sort (1764, 1026);
+ for (p = 2 ; p < 444 ; p += 17)
+ for (n = 2 ; n < 1026 ; n += 42 + p)
diff --git a/patches/mpfr/3.1.3/270-cmp_d.patch b/patches/mpfr/3.1.3/270-cmp_d.patch
new file mode 100644
index 0000000..f22e27a
--- /dev/null
+++ b/patches/mpfr/3.1.3/270-cmp_d.patch
@@ -0,0 +1,219 @@
+diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES
+--- mpfr-3.1.3-a/PATCHES 2016-02-23 12:28:35.578442642 +0000
++++ mpfr-3.1.3-b/PATCHES 2016-02-23 12:28:35.602442321 +0000
+@@ -0,0 +1 @@
++cmp_d
+diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION
+--- mpfr-3.1.3-a/VERSION 2016-02-23 07:55:54.052346433 +0000
++++ mpfr-3.1.3-b/VERSION 2016-02-23 12:28:35.602442321 +0000
+@@ -1 +1 @@
+-3.1.3-p16
++3.1.3-p17
+diff -Naurd mpfr-3.1.3-a/src/cmp_d.c mpfr-3.1.3-b/src/cmp_d.c
+--- mpfr-3.1.3-a/src/cmp_d.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/cmp_d.c 2016-02-23 12:28:35.590442481 +0000
+@@ -27,12 +27,19 @@
+ {
+ mpfr_t tmp;
+ int res;
++ MPFR_SAVE_EXPO_DECL (expo);
++
++ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (tmp, IEEE_DBL_MANT_DIG);
+ res = mpfr_set_d (tmp, d, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
++
++ mpfr_clear_flags ();
+ res = mpfr_cmp (b, tmp);
+- mpfr_clear (tmp);
++ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
++ mpfr_clear (tmp);
++ MPFR_SAVE_EXPO_FREE (expo);
+ return res;
+ }
+diff -Naurd mpfr-3.1.3-a/src/cmp_ld.c mpfr-3.1.3-b/src/cmp_ld.c
+--- mpfr-3.1.3-a/src/cmp_ld.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/src/cmp_ld.c 2016-02-23 12:28:35.590442481 +0000
+@@ -27,12 +27,19 @@
+ {
+ mpfr_t tmp;
+ int res;
++ MPFR_SAVE_EXPO_DECL (expo);
++
++ MPFR_SAVE_EXPO_MARK (expo);
+
+ mpfr_init2 (tmp, MPFR_LDBL_MANT_DIG);
+ res = mpfr_set_ld (tmp, d, MPFR_RNDN);
+ MPFR_ASSERTD (res == 0);
++
++ mpfr_clear_flags ();
+ res = mpfr_cmp (b, tmp);
+- mpfr_clear (tmp);
++ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
+
++ mpfr_clear (tmp);
++ MPFR_SAVE_EXPO_FREE (expo);
+ return res;
+ }
+diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h
+--- mpfr-3.1.3-a/src/mpfr.h 2016-02-23 07:55:54.052346433 +0000
++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 12:28:35.598442376 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 1
+ #define MPFR_VERSION_PATCHLEVEL 3
+-#define MPFR_VERSION_STRING "3.1.3-p16"
++#define MPFR_VERSION_STRING "3.1.3-p17"
+
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c
+--- mpfr-3.1.3-a/src/version.c 2016-02-23 07:55:54.052346433 +0000
++++ mpfr-3.1.3-b/src/version.c 2016-02-23 12:28:35.598442376 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+- return "3.1.3-p16";
++ return "3.1.3-p17";
+ }
+diff -Naurd mpfr-3.1.3-a/tests/tcmp_d.c mpfr-3.1.3-b/tests/tcmp_d.c
+--- mpfr-3.1.3-a/tests/tcmp_d.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tcmp_d.c 2016-02-23 12:28:35.590442481 +0000
+@@ -29,8 +29,10 @@
+ main (void)
+ {
+ mpfr_t x;
++ mpfr_exp_t emin;
+
+ tests_start_mpfr ();
++ emin = mpfr_get_emin ();
+
+ mpfr_init2(x, IEEE_DBL_MANT_DIG);
+
+@@ -67,16 +69,31 @@
+ exit (1);
+ }
+
++ /* Test in reduced exponent range. */
++ set_emin (1);
++ mpfr_set_ui (x, 1, MPFR_RNDN);
++ if (mpfr_cmp_d (x, 0.9) <= 0)
++ {
++ printf ("Error in reduced exponent range.\n");
++ exit (1);
++ }
++ set_emin (emin);
++
+ #if !defined(MPFR_ERRDIVZERO)
+ /* Check NAN */
+ {
+ int c;
+
+- mpfr_clear_erangeflag ();
++ mpfr_clear_flags ();
+ c = mpfr_cmp_d (x, DBL_NAN);
+- if (c != 0 || !mpfr_erangeflag_p ())
++ if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
+ {
+ printf ("ERROR for NAN (1)\n");
++ printf ("Expected 0, got %d\n", c);
++ printf ("Expected flags:");
++ flags_out (MPFR_FLAGS_ERANGE);
++ printf ("Got flags: ");
++ flags_out (__gmpfr_flags);
+ #ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+@@ -84,12 +101,18 @@
+ #endif
+ exit (1);
+ }
++
+ mpfr_set_nan (x);
+- mpfr_clear_erangeflag ();
++ mpfr_clear_flags ();
+ c = mpfr_cmp_d (x, 2.0);
+- if (c != 0 || !mpfr_erangeflag_p ())
++ if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
+ {
+ printf ("ERROR for NAN (2)\n");
++ printf ("Expected 0, got %d\n", c);
++ printf ("Expected flags:");
++ flags_out (MPFR_FLAGS_ERANGE);
++ printf ("Got flags: ");
++ flags_out (__gmpfr_flags);
+ #ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+diff -Naurd mpfr-3.1.3-a/tests/tcmp_ld.c mpfr-3.1.3-b/tests/tcmp_ld.c
+--- mpfr-3.1.3-a/tests/tcmp_ld.c 2015-06-19 19:55:10.000000000 +0000
++++ mpfr-3.1.3-b/tests/tcmp_ld.c 2016-02-23 12:28:35.590442481 +0000
+@@ -28,8 +28,10 @@
+ main (void)
+ {
+ mpfr_t x;
++ mpfr_exp_t emin;
+
+ tests_start_mpfr ();
++ emin = mpfr_get_emin ();
+
+ mpfr_init2(x, MPFR_LDBL_MANT_DIG);
+
+@@ -66,16 +68,31 @@
+ exit (1);
+ }
+
++ /* Test in reduced exponent range. */
++ set_emin (1);
++ mpfr_set_ui (x, 1, MPFR_RNDN);
++ if (mpfr_cmp_ld (x, 0.9) <= 0)
++ {
++ printf ("Error in reduced exponent range.\n");
++ exit (1);
++ }
++ set_emin (emin);
++
+ #if !defined(MPFR_ERRDIVZERO)
+ /* Check NAN */
+ {
+ int c;
+
+- mpfr_clear_erangeflag ();
++ mpfr_clear_flags ();
+ c = mpfr_cmp_ld (x, DBL_NAN);
+- if (c != 0 || !mpfr_erangeflag_p ())
++ if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
+ {
+ printf ("ERROR for NAN (1)\n");
++ printf ("Expected 0, got %d\n", c);
++ printf ("Expected flags:");
++ flags_out (MPFR_FLAGS_ERANGE);
++ printf ("Got flags: ");
++ flags_out (__gmpfr_flags);
+ #ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "
+@@ -83,12 +100,18 @@
+ #endif
+ exit (1);
+ }
++
+ mpfr_set_nan (x);
+- mpfr_clear_erangeflag ();
++ mpfr_clear_flags ();
+ c = mpfr_cmp_ld (x, 2.0);
+- if (c != 0 || !mpfr_erangeflag_p ())
++ if (c != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
+ {
+ printf ("ERROR for NAN (2)\n");
++ printf ("Expected 0, got %d\n", c);
++ printf ("Expected flags:");
++ flags_out (MPFR_FLAGS_ERANGE);
++ printf ("Got flags: ");
++ flags_out (__gmpfr_flags);
+ #ifdef MPFR_NANISNAN
+ printf ("The reason is that NAN == NAN. Please look at the configure "
+ "output\nand Section \"In case of problem\" of the INSTALL "