diff options
Diffstat (limited to 'patches/mpfr/3.1.3/240-rem1.patch')
-rw-r--r-- | patches/mpfr/3.1.3/240-rem1.patch | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/patches/mpfr/3.1.3/240-rem1.patch b/patches/mpfr/3.1.3/240-rem1.patch new file mode 100644 index 00000000..9d5e3c1d --- /dev/null +++ b/patches/mpfr/3.1.3/240-rem1.patch @@ -0,0 +1,337 @@ +diff -Naurd mpfr-3.1.3-a/PATCHES mpfr-3.1.3-b/PATCHES +--- mpfr-3.1.3-a/PATCHES 2016-02-23 07:54:06.617533218 +0000 ++++ mpfr-3.1.3-b/PATCHES 2016-02-23 07:54:06.641532898 +0000 +@@ -0,0 +1 @@ ++rem1 +diff -Naurd mpfr-3.1.3-a/VERSION mpfr-3.1.3-b/VERSION +--- mpfr-3.1.3-a/VERSION 2016-02-23 07:43:23.726095285 +0000 ++++ mpfr-3.1.3-b/VERSION 2016-02-23 07:54:06.641532898 +0000 +@@ -1 +1 @@ +-3.1.3-p13 ++3.1.3-p14 +diff -Naurd mpfr-3.1.3-a/src/mpfr.h mpfr-3.1.3-b/src/mpfr.h +--- mpfr-3.1.3-a/src/mpfr.h 2016-02-23 07:43:23.726095285 +0000 ++++ mpfr-3.1.3-b/src/mpfr.h 2016-02-23 07:54:06.641532898 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 3 +-#define MPFR_VERSION_STRING "3.1.3-p13" ++#define MPFR_VERSION_STRING "3.1.3-p14" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.3-a/src/rem1.c mpfr-3.1.3-b/src/rem1.c +--- mpfr-3.1.3-a/src/rem1.c 2015-06-19 19:55:10.000000000 +0000 ++++ mpfr-3.1.3-b/src/rem1.c 2016-02-23 07:54:06.633533004 +0000 +@@ -59,6 +59,7 @@ + mpfr_exp_t ex, ey; + int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x); + mpz_t mx, my, r; ++ int tiny = 0; + + MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ); + +@@ -109,13 +110,27 @@ + if (ex <= ey) + { + /* q = x/y = mx/(my*2^(ey-ex)) */ +- mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */ +- if (rnd_q == MPFR_RNDZ) +- /* 0 <= |r| <= |my|, r has the same sign as mx */ +- mpz_tdiv_qr (mx, r, mx, my); ++ ++ /* First detect cases where q=0, to avoid creating a huge number ++ my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy = ++ mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and ++ y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1 ++ the quotient is 0 */ ++ if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) < ++ ey + (mpfr_exp_t) mpz_sizeinbase (my, 2)) ++ { ++ tiny = 1; ++ mpz_set (r, mx); ++ mpz_set_ui (mx, 0); ++ } + else +- /* 0 <= |r| <= |my|, r has the same sign as my */ +- mpz_fdiv_qr (mx, r, mx, my); ++ { ++ mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */ ++ ++ /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */ ++ mpz_tdiv_qr (mx, r, mx, my); ++ /* 0 <= |r| <= |my|, r has the same sign as mx */ ++ } + + if (rnd_q == MPFR_RNDN) + q_is_odd = mpz_tstbit (mx, 0); +@@ -181,7 +196,20 @@ + /* FIXME: the comparison 2*r < my could be done more efficiently + at the mpn level */ + mpz_mul_2exp (r, r, 1); +- compare = mpz_cmpabs (r, my); ++ /* if tiny=1, we should compare r with my*2^(ey-ex) */ ++ if (tiny) ++ { ++ if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) < ++ ey + (mpfr_exp_t) mpz_sizeinbase (my, 2)) ++ compare = 0; /* r*2^ex < my*2^ey */ ++ else ++ { ++ mpz_mul_2exp (my, my, ey - ex); ++ compare = mpz_cmpabs (r, my); ++ } ++ } ++ else ++ compare = mpz_cmpabs (r, my); + mpz_fdiv_q_2exp (r, r, 1); + compare = ((compare > 0) || + ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd)); +diff -Naurd mpfr-3.1.3-a/src/version.c mpfr-3.1.3-b/src/version.c +--- mpfr-3.1.3-a/src/version.c 2016-02-23 07:43:23.726095285 +0000 ++++ mpfr-3.1.3-b/src/version.c 2016-02-23 07:54:06.641532898 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.3-p13"; ++ return "3.1.3-p14"; + } +diff -Naurd mpfr-3.1.3-a/tests/tfmod.c mpfr-3.1.3-b/tests/tfmod.c +--- mpfr-3.1.3-a/tests/tfmod.c 2015-06-19 19:55:10.000000000 +0000 ++++ mpfr-3.1.3-b/tests/tfmod.c 2016-02-23 07:54:06.633533004 +0000 +@@ -137,89 +137,90 @@ + special (void) + { + int inexact; +- mpfr_t x, y, r, nan; +- mpfr_inits (x, y, r, nan, (mpfr_ptr) 0); ++ mpfr_t x, y, r, t; + +- mpfr_set_nan (nan); ++ mpfr_inits (x, y, r, t, (mpfr_ptr) 0); ++ ++ mpfr_set_nan (t); + + /* fmod (NaN, NaN) is NaN */ + mpfr_set_nan (x); + mpfr_set_nan (y); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (NaN, +0) is NaN */ + mpfr_set_ui (y, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+1, 0) is NaN */ + mpfr_set_ui (x, 1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (0, 0) is NaN */ + mpfr_set_ui (x, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +0) is NaN */ + mpfr_set_inf (x, +1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +0) is NaN */ + mpfr_set_inf (x, -1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, -0) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +1) is NaN */ + mpfr_set_ui (y, +1, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +1) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, -inf) is NaN */ + mpfr_set_inf (y, -1); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, -inf) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (-inf, +inf) is NaN */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+inf, +inf) is NaN */ + mpfr_neg (x, x, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (x, +inf) = x, if x is finite */ + mpfr_set_ui (x, 1, MPFR_RNDN); +@@ -271,13 +272,13 @@ + mpfr_set_ui (y, 0, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, -0) is NaN */ + mpfr_neg (y, y, MPFR_RNDN); + inexact = mpfr_fmod (r, x, y, MPFR_RNDN); + if (!mpfr_nan_p (r) || inexact != 0) +- test_failed (r, nan, 0, inexact, x, y, MPFR_RNDN); ++ test_failed (r, t, 0, inexact, x, y, MPFR_RNDN); + + /* fmod (+0, +1) = +0 */ + mpfr_set_ui (y, 1, MPFR_RNDN); +@@ -303,7 +304,18 @@ + if (!mpfr_equal_p (r, x) || inexact != 0) + test_failed (r, x, 0, inexact, x, y, MPFR_RNDN); + +- mpfr_clears (x, y, r, nan, (mpfr_ptr) 0); ++ mpfr_set_prec (x, 380); ++ mpfr_set_prec (y, 385); ++ mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E0"); ++ mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1"); ++ mpfr_set_prec (r, 2); ++ inexact = mpfr_fmod (r, x, y, MPFR_RNDA); ++ mpfr_set_prec (t, 2); ++ mpfr_set_ui_2exp (t, 3, -5, MPFR_RNDN); ++ if (mpfr_cmp_ui_2exp (r, 3, -5) || inexact <= 0) ++ test_failed (r, t, 1, inexact, x, y, MPFR_RNDA); ++ ++ mpfr_clears (x, y, r, t, (mpfr_ptr) 0); + return; + } + +@@ -313,6 +325,7 @@ + { + mpfr_t x, y, r; + int inexact; ++ + mpfr_inits2 (100, x, y, r, (mpfr_ptr) 0); + + mpfr_set_prec (x, 3); +@@ -353,7 +366,46 @@ + mpfr_sin (y, y, MPFR_RNDN); + check (r, x, y, MPFR_RNDN); + +- mpfr_clears(r, x, y, (mpfr_ptr) 0); ++ mpfr_clears (x, y, r, (mpfr_ptr) 0); ++} ++ ++static void ++bug20160217 (void) ++{ ++ mpfr_t x, y, r; ++ int inexact, i; ++ mpfr_exp_t emin, emax; ++ ++ mpfr_inits2 (53, x, y, r, (mpfr_ptr) 0); ++ ++ emin = mpfr_get_emin (); ++ emax = mpfr_get_emax (); ++ ++ for (i = 0; i <= 1; i++) ++ { ++ mpfr_set_zero (x, 1); ++ mpfr_nextabove (x); ++ mpfr_set_inf (y, 1); ++ mpfr_nextbelow (y); ++ inexact = mpfr_fmod (r, x, y, MPFR_RNDN); ++ if (!mpfr_equal_p (r, x) || inexact != 0) ++ { ++ printf ("Error for mpfr_fmod (r, nextabove(0), nextbelow(+inf)," ++ " MPFR_RNDN)%s\n", i ? "extended exponent range" : ""); ++ printf ("Expected inex = 0, r = "); ++ mpfr_dump (x); ++ printf ("Got inex = %d, r = ", inexact); ++ mpfr_dump (r); ++ exit (1); ++ } ++ set_emin (MPFR_EMIN_MIN); ++ set_emax (MPFR_EMAX_MAX); ++ } ++ ++ set_emin (emin); ++ set_emax (emax); ++ ++ mpfr_clears (x, y, r, (mpfr_ptr) 0); + } + + int +@@ -362,6 +414,7 @@ + tests_start_mpfr (); + + bug20090519 (); ++ bug20160217 (); + + test_generic (2, 100, 100); + +diff -Naurd mpfr-3.1.3-a/tests/tremquo.c mpfr-3.1.3-b/tests/tremquo.c +--- mpfr-3.1.3-a/tests/tremquo.c 2015-06-19 19:55:10.000000000 +0000 ++++ mpfr-3.1.3-b/tests/tremquo.c 2016-02-23 07:54:06.633533004 +0000 +@@ -59,6 +59,7 @@ + { + mpfr_t x, y, r; + long q[1]; ++ int inex; + + if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */ + { +@@ -281,6 +282,15 @@ + MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0); + MPFR_ASSERTN (q[0] == 0); + ++ mpfr_set_prec (x, 380); ++ mpfr_set_prec (y, 385); ++ mpfr_set_str_binary (x, "0.11011010010110011101011000100100101100101011010001011100110001100101111001010100001011111110111100101110101010110011010101000100000100011101101100001011101110100111101111111010001001000010000110010110011100111000001110111010000100101001010111100100010001101001110100011110010000000001110001111001101100111011001000110110011100100011111110010100011001000001001011010111010000000000E-2"); ++ mpfr_set_str_binary (y, "0.1100011000011101011010001100010111001110110111001101010010111100111100011010010011011101111101111001010111111110001001100001111101001000000010100101111001001110010110000111001000101010111001001000100101011111000010100110001111000110011011010101111101100110010101011010011101100001011101001000101111110110110110000001001101110111110110111110111111001001011110001110011111100000000000000E-1"); ++ mpfr_set_prec (r, 2); ++ inex = mpfr_remainder (r, x, y, MPFR_RNDA); ++ MPFR_ASSERTN(mpfr_cmp_si_2exp (r, -3, -4) == 0); ++ MPFR_ASSERTN(inex < 0); ++ + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (r); |