diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:52:13.875783093 +0000 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:52:13.911782747 +0000 @@ -0,0 +1 @@ +cmp_q-special diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION --- mpfr-4.0.1-a/VERSION 2018-04-27 12:50:10.624974512 +0000 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:52:13.911782747 +0000 @@ -1 +1 @@ -4.0.1-p4 +4.0.1-p5 diff -Naurd mpfr-4.0.1-a/src/gmp_op.c mpfr-4.0.1-b/src/gmp_op.c --- mpfr-4.0.1-a/src/gmp_op.c 2018-01-09 12:30:58.000000000 +0000 +++ mpfr-4.0.1-b/src/gmp_op.c 2018-04-27 12:52:13.899782862 +0000 @@ -452,11 +452,15 @@ mpfr_prec_t p; MPFR_SAVE_EXPO_DECL (expo); - if (MPFR_UNLIKELY (mpq_denref (q) == 0)) + if (MPFR_UNLIKELY (mpz_sgn (mpq_denref (q)) == 0)) { /* q is an infinity or NaN */ - mpfr_init2 (t, 2); + mpfr_flags_t old_flags; + + mpfr_init2 (t, MPFR_PREC_MIN); + old_flags = __gmpfr_flags; mpfr_set_q (t, q, MPFR_RNDN); + __gmpfr_flags = old_flags; res = mpfr_cmp (x, t); mpfr_clear (t); return res; diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:50:10.620974551 +0000 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:52:13.907782785 +0000 @@ -27,7 +27,7 @@ #define MPFR_VERSION_MAJOR 4 #define MPFR_VERSION_MINOR 0 #define MPFR_VERSION_PATCHLEVEL 1 -#define MPFR_VERSION_STRING "4.0.1-p4" +#define MPFR_VERSION_STRING "4.0.1-p5" /* User macros: MPFR_USE_FILE: Define it to make MPFR define functions dealing diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:50:10.624974512 +0000 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:52:13.911782747 +0000 @@ -25,5 +25,5 @@ const char * mpfr_get_version (void) { - return "4.0.1-p4"; + return "4.0.1-p5"; } diff -Naurd mpfr-4.0.1-a/tests/tgmpop.c mpfr-4.0.1-b/tests/tgmpop.c --- mpfr-4.0.1-a/tests/tgmpop.c 2018-01-09 12:30:58.000000000 +0000 +++ mpfr-4.0.1-b/tests/tgmpop.c 2018-04-27 12:52:13.899782862 +0000 @@ -307,16 +307,39 @@ mpfr_init2 (z, MPFR_PREC_MIN); mpq_init (y); - /* check the erange flag when x is NaN */ + /* Check the flags when x is NaN: the erange flags must be set, and + only this one. */ mpfr_set_nan (x); mpq_set_ui (y, 17, 1); - mpfr_clear_erangeflag (); + mpfr_clear_flags (); res1 = mpfr_cmp_q (x, y); - if (res1 != 0 || mpfr_erangeflag_p () == 0) + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) { printf ("Error for mpfr_cmp_q (NaN, 17)\n"); printf ("Return value: expected 0, got %d\n", res1); - printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ()); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); + exit (1); + } + + /* Check the flags when y is NaN: the erange flags must be set, and + only this one. */ + mpfr_set_ui (x, 42, MPFR_RNDN); + /* A NaN rational is represented by 0/0 (MPFR extension). */ + mpz_set_ui (mpq_numref (y), 0); + mpz_set_ui (mpq_denref (y), 0); + mpfr_clear_flags (); + res1 = mpfr_cmp_q (x, y); + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE) + { + printf ("Error for mpfr_cmp_q (42, NaN)\n"); + printf ("Return value: expected 0, got %d\n", res1); + printf ("Expected flags:"); + flags_out (MPFR_FLAGS_ERANGE); + printf ("Got flags: "); + flags_out (__gmpfr_flags); exit (1); } @@ -341,6 +364,55 @@ } } } + + /* check for y = 1/0 */ + mpz_set_ui (mpq_numref (y), 1); + mpz_set_ui (mpq_denref (y), 0); + mpfr_set_ui (x, 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0); + mpfr_set_inf (x, -1); + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0); + mpfr_set_inf (x, +1); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + mpfr_set_nan (x); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + + /* check for y = -1/0 */ + mpz_set_si (mpq_numref (y), -1); + mpz_set_ui (mpq_denref (y), 0); + mpfr_set_ui (x, 1, MPFR_RNDN); + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0); + mpfr_set_inf (x, -1); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + mpfr_set_inf (x, +1); + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0); + mpfr_set_nan (x); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + + /* check for y = 0/0 */ + mpz_set_ui (mpq_numref (y), 0); + mpz_set_ui (mpq_denref (y), 0); + mpfr_set_ui (x, 1, MPFR_RNDN); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + mpfr_set_inf (x, -1); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + mpfr_set_inf (x, +1); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + mpfr_set_nan (x); + mpfr_clear_erangeflag (); + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0); + MPFR_ASSERTN(mpfr_erangeflag_p ()); + mpq_clear (y); mpfr_clear (x); mpfr_clear (z);