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>
This commit is contained in:
Kirill K. Smirnov 2016-09-18 00:01:42 +03:00
parent af1850f76f
commit 2e6a56d1cc
54 changed files with 11221 additions and 0 deletions

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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:

View File

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

View File

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

View File

@ -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";
}

View File

@ -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";
}

View File

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

View File

@ -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";
}

View File

@ -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");

View File

@ -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");

View File

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

View File

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

View File

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

View File

@ -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";
}

View File

@ -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
}
-

View File

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

View File

@ -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 */

View File

@ -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";
}

View File

@ -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";
}

View File

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

View File

@ -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";
}

View File

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

View File

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

View File

@ -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";
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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";
}

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

@ -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)

View File

@ -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 "