crosstool-ng/packages/mpfr/3.1.3/240-rem1.patch

338 lines
12 KiB
Diff
Raw Normal View History

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