[Gmp-commit] /var/hg/gmp: Fix mpq mord_2exp bug, enhance related testing.

mercurial at gmplib.org mercurial at gmplib.org
Mon Nov 12 20:25:33 CET 2012


details:   /var/hg/gmp/rev/176bf5aec761
changeset: 15107:176bf5aec761
user:      Torbjorn Granlund <tege at gmplib.org>
date:      Mon Nov 12 20:25:26 2012 +0100
description:
Fix mpq mord_2exp bug, enhance related testing.

diffstat:

 ChangeLog             |   5 +++
 mpq/md_2exp.c         |   4 +-
 tests/mpq/t-md_2exp.c |  65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diffs (110 lines):

diff -r 47aea8fab3ce -r 176bf5aec761 ChangeLog
--- a/ChangeLog	Sat Nov 10 14:35:44 2012 +0100
+++ b/ChangeLog	Mon Nov 12 20:25:26 2012 +0100
@@ -1,3 +1,8 @@
+2012-11-12  Torbjorn Granlund  <tege at gmplib.org>
+
+	* mpq/md_2exp.c: Use MPN_COPY_INCR, not MPN_COPY_DECR.
+	* tests/mpq/t-md_2exp.c (check_random): New function.
+
 2012-11-10  Torbjorn Granlund  <tege at gmplib.org>
 
 	* mpn/generic/remove.c (mpn_bdiv_qr_wrap): Make static.
diff -r 47aea8fab3ce -r 176bf5aec761 mpq/md_2exp.c
--- a/mpq/md_2exp.c	Sat Nov 10 14:35:44 2012 +0100
+++ b/mpq/md_2exp.c	Mon Nov 12 20:25:26 2012 +0100
@@ -52,9 +52,9 @@
 
   if ((plow & 1) || n == 0)
     {
-      /* need DECR when src==dst */
+      /* need INCR when src==dst */
       if (p != rdst_ptr)
-        MPN_COPY_DECR (rdst_ptr, p, len);
+        MPN_COPY_INCR (rdst_ptr, p, len);
     }
   else
     {
diff -r 47aea8fab3ce -r 176bf5aec761 tests/mpq/t-md_2exp.c
--- a/tests/mpq/t-md_2exp.c	Sat Nov 10 14:35:44 2012 +0100
+++ b/tests/mpq/t-md_2exp.c	Mon Nov 12 20:25:26 2012 +0100
@@ -29,8 +29,69 @@
   const char     *den;
 };
 
+void
+check_random ()
+{
+  gmp_randstate_ptr rands;
+  mpz_t bs;
+  unsigned long arg_size, size_range;
+  mpq_t q, r;
+  int i;
+  mp_bitcnt_t shift;
+  int reps = 10000;
+
+  rands = RANDS;
+
+  mpz_init (bs);
+  mpq_init (q);
+  mpq_init (r);
+
+  for (i = 0; i < reps; i++)
+    {
+      mpz_urandomb (bs, rands, 32);
+      size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */
+
+      mpz_urandomb (bs, rands, size_range);
+      arg_size = mpz_get_ui (bs);
+      mpz_rrandomb (mpq_numref (q), rands, arg_size);
+      do
+	{
+	  mpz_urandomb (bs, rands, size_range);
+	  arg_size = mpz_get_ui (bs);
+	  mpz_rrandomb (mpq_denref (q), rands, arg_size);
+	}
+      while (mpz_sgn (mpq_denref (q)) == 0);
+
+      /* We now have a random rational in q, albeit an unnormalised one.  The
+	 lack of normalisation should not matter here, so let's save the time a
+	 gcd would require.  */
+
+      mpz_urandomb (bs, rands, 32);
+      shift = mpz_get_ui (bs) % 4096;
+
+      mpq_mul_2exp (r, q, shift);
+
+      if (mpq_cmp (r, q) < 0)
+	{
+	  printf ("mpq_mul_2exp wrong on random\n");
+	  abort ();
+	}
+
+      mpq_div_2exp (r, r, shift);
+
+      if (mpq_cmp (r, q) != 0)
+	{
+	  printf ("mpq_mul_2exp or mpq_div_2exp wrong on random\n");
+	  abort ();
+	}
+    }
+  mpq_clear (q);
+  mpq_clear (r);
+  mpz_clear (bs);
+}
+
 int
-main (void)
+main (int argc, char **argv)
 {
   static const struct {
     struct pair_t  left;
@@ -173,6 +234,8 @@
         }
     }
 
+  check_random ();
+
   mpq_clear (sep);
   mpq_clear (got);
   mpq_clear (want);


More information about the gmp-commit mailing list