[Gmp-commit] /var/hg/gmp: 2 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Mon May 28 04:25:12 UTC 2018
details: /var/hg/gmp/rev/1f8a8fefb5c2
changeset: 17631:1f8a8fefb5c2
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon May 28 06:22:20 2018 +0200
description:
tests/mpz/t-gcd_ui.c (check_ui_factors): New check triggering a possible bug.
details: /var/hg/gmp/rev/e4849ae7c974
changeset: 17632:e4849ae7c974
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Mon May 28 06:24:27 2018 +0200
description:
mpn/generic/gcd_1.c: Avoid an undefined behaviour
diffstat:
mpn/generic/gcd_1.c | 2 +-
tests/mpz/t-gcd_ui.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 1 deletions(-)
diffs (122 lines):
diff -r aab8a010d10f -r e4849ae7c974 mpn/generic/gcd_1.c
--- a/mpn/generic/gcd_1.c Mon May 21 00:13:27 2018 +0200
+++ b/mpn/generic/gcd_1.c Mon May 28 06:24:27 2018 +0200
@@ -184,7 +184,7 @@
}
count_trailing_zeros (c, t);
#endif
- ulimb >>= (c + 1);
+ ulimb = (ulimb >> c) >> 1;
}
vlimb = (vlimb << 1) | 1;
diff -r aab8a010d10f -r e4849ae7c974 tests/mpz/t-gcd_ui.c
--- a/tests/mpz/t-gcd_ui.c Mon May 21 00:13:27 2018 +0200
+++ b/tests/mpz/t-gcd_ui.c Mon May 28 06:24:27 2018 +0200
@@ -50,12 +50,106 @@
mpz_clear (x);
}
+static void
+check_ui_factors (void)
+{
+#define NUM_FACTORS 9
+ static const char* factors[NUM_FACTORS] = {
+ "641", "274177", "3", "5", "17", "257", "65537",
+ "59649589127497217", "1238926361552897" };
+ unsigned long got;
+ mpz_t x, b, d, f, g;
+ int i, j;
+ gmp_randstate_ptr rands;
+
+ if (GMP_NUMB_BITS < 5 || GMP_NUMB_BITS == 8
+ || GMP_NUMB_BITS == 16 || GMP_NUMB_BITS > 511)
+ {
+ printf ("No usable factors for 2^%i+1.\n", GMP_NUMB_BITS);
+ return;
+ }
+
+ mpz_init (x);
+ mpz_init (d);
+ mpz_init (f);
+ mpz_init (g);
+
+ mpz_setbit (x, GMP_NUMB_BITS);
+ mpz_add_ui (x, x, 1);
+
+ for (i = 0; i < NUM_FACTORS; ++i)
+ {
+ mpz_set_str (f, factors[i], 10);
+ if (mpz_divisible_p (x, f))
+ {
+ mpz_mul_2exp (f, f, 1);
+ /* d is an odd multiple of the factor f, exactly filling a limb. */
+ mpz_sub (d, x, f);
+ /* f = 2^GMP_NUMB_BITS mod d. */
+ mpz_sub_ui (f, f, 1);
+ break;
+ }
+ }
+
+ mpz_gcd (g, f, d);
+ if (mpz_even_p (d) || mpz_cmp (d, f) <= 0 || mpz_cmp_ui (g, 1) != 0)
+ {
+ printf ("No usable factor found.\n");
+ abort ();
+ }
+
+ rands = RANDS;
+ mpz_mul_ui (x, d, gmp_urandomm_ui (rands, 30000) + 1);
+
+ mpz_init (b);
+ mpz_setbit (b, GMP_NUMB_BITS - 1);
+ for (j = 0; j < 4; ++j)
+ {
+ mpz_add (x, x, b);
+
+ for (i = 1; i >= -1; --i)
+ {
+ if (mpz_fits_ulong_p (d)
+ && ((got = mpz_gcd_ui (NULL, x, mpz_get_ui (d)))
+ != (i != 0 ? 1 : mpz_get_ui (d))))
+ {
+ printf ("mpz_gcd_ui (f, kV+%i*2^%i, V): error (j = %i)\n", i, GMP_NUMB_BITS - 1, j);
+ printf (" return %#lx\n", got);
+ printf (" should be %#lx\n", (i != 0 ? 1 : mpz_get_ui (d)));
+ abort ();
+ }
+
+ mpz_gcd (g, x, d);
+ if ((mpz_cmp_ui (g, 1) == 0) != (i != 0))
+ {
+ printf ("mpz_gcd (f, kV+%i*2^%i, V): error (j = %i)\n", i, GMP_NUMB_BITS - 1, j);
+ printf (" should%s be one.\n",(i != 0 ? "" : " not"));
+ abort ();
+ }
+
+ mpz_sub (x, x, b);
+ }
+ /* Back to the original x. */
+ mpz_addmul_ui (x, b, 2);
+ mpz_mul (b, b, f);
+ mpz_mod (b, b, d);
+ }
+
+ mpz_clear (g);
+ mpz_clear (x);
+ mpz_clear (f);
+ mpz_clear (d);
+ mpz_clear (b);
+}
+
+
int
main (void)
{
tests_start ();
check_ui_range ();
+ check_ui_factors ();
tests_end ();
exit (0);
More information about the gmp-commit
mailing list