[Gmp-commit] /var/hg/gmp-proj/mini-gmp: 3 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Sun Jan 1 16:24:15 CET 2012


details:   /var/hg/gmp-proj/mini-gmp/rev/e2fc29e4f7ea
changeset: 27:e2fc29e4f7ea
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sun Jan 01 14:17:32 2012 +0100
description:
Implemented mpz_tdiv_qr_ui.

details:   /var/hg/gmp-proj/mini-gmp/rev/411a99a73ed2
changeset: 28:411a99a73ed2
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sun Jan 01 16:16:05 2012 +0100
description:
Implemented more div function variants.

details:   /var/hg/gmp-proj/mini-gmp/rev/7c34a20624ec
changeset: 29:7c34a20624ec
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sun Jan 01 16:24:11 2012 +0100
description:
mpz_cmpabs and mpz_cmpabs_ui

diffstat:

 mini-gmp.c    |  143 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 mini-gmp.h    |   16 ++++++
 tests/t-div.c |   85 +++++++++++++++++++---------------
 3 files changed, 197 insertions(+), 47 deletions(-)

diffs (truncated from 317 to 300 lines):

diff -r 7fa37b2ad847 -r 7c34a20624ec mini-gmp.c
--- a/mini-gmp.c	Sat Dec 31 09:42:23 2011 +0100
+++ b/mini-gmp.c	Sun Jan 01 16:24:11 2012 +0100
@@ -29,21 +29,13 @@
 /* Missing functions, needed by guile:
 
      mpz_and
-     mpz_cdiv_qr_ui
-     mpz_cdiv_q_ui
-     mpz_cdiv_ui
-     mpz_cmpabs
      mpz_cmp_d
      mpz_com
-     mpz_divexact
      mpz_divexact_ui
      mpz_divisible_p
      mpz_divisible_ui_p
      mpz_even_p
      mpz_export
-     mpz_fdiv_qr_ui
-     mpz_fdiv_q_ui
-     mpz_fdiv_ui
      mpz_gcd
      mpz_gcd_ui
      mpz_getlimbn
@@ -55,8 +47,6 @@
      mpz_popcount
      mpz_powm
      mpz_sqrtrem
-     mpz_tdiv_q_ui
-     mpz_tdiv_ui
      mpz_tstbit
      mpz_xor
  */
@@ -1262,6 +1252,32 @@
     return 0;
 }
 
+int
+mpz_cmpabs_ui (const mpz_t u, unsigned long v)
+{
+  mp_size_t un = ABS(u->_mp_size);
+  mp_limb_t ul;
+
+  if (un > 1)
+    return 1;
+
+  ul = (un == 1) ? u->_mp_d[0] : 0;
+
+  if (ul > v)
+    return 1;
+  else if (ul < v)
+    return -1;
+  else
+    return 0;
+}
+
+int
+mpz_cmpabs (const mpz_t u, const mpz_t v)
+{
+  return mpn_cmp4 (u->_mp_d, ABS(u->_mp_size),
+		   v->_mp_d, ABS(v->_mp_size));
+}
+
 /* Adds to the absolute value. Returns new size, but doesn't store it. */
 static mp_size_t
 abs_add_ui (mpz_t r, const mpz_t a, unsigned long b)
@@ -1664,6 +1680,113 @@
   mpz_div_qr (NULL, r, n, d, DIV_TRUNC);
 }
 
+unsigned long
+mpz_div_qr_ui (mpz_t q, mpz_t r,
+	       const mpz_t n, unsigned long d, enum div_round_mode mode)
+{
+  mp_size_t ns, qn;
+  mp_ptr qp;
+  mp_limb_t rl;
+  mp_size_t rs;
+
+  ns = n->_mp_size;
+  if (ns == 0)
+    {
+      q->_mp_size = r->_mp_size = 0;
+      return 0;
+    }
+
+  qn = ABS (ns);
+  if (q)
+    qp = MPZ_REALLOC (q, qn);
+  else
+    qp = NULL;
+
+  rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d);
+  assert (rl < d);
+
+  rs = rl > 0;
+  rs = (ns < 0) ? -rs : rs;
+
+  if (rl > 0 && ( (mode == DIV_FLOOR && ns < 0)
+		  || (mode == DIV_CEIL && ns >= 0)))
+    {
+      if (q)
+	assert_nocarry (mpn_add_1 (qp, qp, qn, 1));
+      rl = d - rl;
+      rs = -rs;
+    }
+
+  if (r)
+    {
+      r->_mp_d[0] = rl;
+      r->_mp_size = rs;
+    }
+  if (q)
+    {
+      qn -= (qp[qn-1] == 0);
+      assert (qn == 0 || qp[qn-1] > 0);
+
+      q->_mp_size = (ns < 0) ? - qn : qn;
+    }
+
+  return rl;
+}
+
+unsigned long
+mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, r, n, d, DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, r, n, d, DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, r, n, d, DIV_TRUNC);
+}
+
+unsigned long
+mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, NULL, n, d, DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, NULL, n, d, DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (q, NULL, n, d, DIV_TRUNC);
+}
+
+unsigned long
+mpz_cdiv_ui (const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (NULL, NULL, n, d, DIV_CEIL);
+}
+
+unsigned long
+mpz_fdiv_ui (const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (NULL, NULL, n, d, DIV_FLOOR);
+}
+
+unsigned long
+mpz_tdiv_ui (const mpz_t n, unsigned long d)
+{
+  return mpz_div_qr_ui (NULL, NULL, n, d, DIV_TRUNC);
+}
+
 void
 mpz_setbit (mpz_t d, mp_bitcnt_t bit_index)
 {
diff -r 7fa37b2ad847 -r 7c34a20624ec mini-gmp.h
--- a/mini-gmp.h	Sat Dec 31 09:42:23 2011 +0100
+++ b/mini-gmp.h	Sun Jan 01 16:24:11 2012 +0100
@@ -86,6 +86,8 @@
 int mpz_cmp_si (const mpz_t, long);
 int mpz_cmp_ui (const mpz_t, unsigned long);
 int mpz_cmp (const mpz_t, const mpz_t);
+int mpz_cmpabs_ui (const mpz_t, unsigned long);
+int mpz_cmpabs (const mpz_t, const mpz_t);
 
 void mpz_swap (mpz_t, mpz_t);
 
@@ -108,6 +110,20 @@
 void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t);
 void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t);
 
+#define mpz_divexact (q, n, d) mpz_tdiv_q ((q), (n), (d))
+
+unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long);
+unsigned long mpz_cdiv_ui (const mpz_t, unsigned long);
+unsigned long mpz_fdiv_ui (const mpz_t, unsigned long);
+unsigned long mpz_tdiv_ui (const mpz_t, unsigned long);
+
+#define mpz_divexact_ui(q, n, d) ((void) mpz_tdiv_q_ui ((q), (n), (d)))
+
 void mpz_setbit (mpz_t, mp_bitcnt_t);
 
 int mpz_fits_slong_p (const mpz_t);
diff -r 7fa37b2ad847 -r 7c34a20624ec tests/t-div.c
--- a/tests/t-div.c	Sat Dec 31 09:42:23 2011 +0100
+++ b/tests/t-div.c	Sun Jan 01 16:24:11 2012 +0100
@@ -15,6 +15,9 @@
   free (buf);
 }
 
+typedef void div_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
+typedef unsigned long div_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
+
 int
 main (int argc, char **argv)
 {
@@ -32,44 +35,52 @@
 
   for (i = 0; i < COUNT; i++)
     {
-      mini_random_div_op (OP_CDIV, MAXBITS, a, b, rq, rr);
-      mpz_cdiv_qr (q, r, a, b);
-      if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
+      unsigned j;
+      for (j = 0; j < 3; j++)
 	{
-	  fprintf (stderr, "mpz_cdiv_qr failed:\n");
-	  dump ("a", a);
-	  dump ("b", b);
-	  dump ("r   ", r);
-	  dump ("rref", rr);
-	  dump ("q   ", q);
-	  dump ("qref", rq);
-	  abort ();
-	}
-      mini_random_div_op (OP_FDIV, MAXBITS, a, b, rq, rr);
-      mpz_fdiv_qr (q, r, a, b);
-      if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
-	{
-	  fprintf (stderr, "mpz_fdiv_qr failed:\n");
-	  dump ("a", a);
-	  dump ("b", b);
-	  dump ("r   ", r);
-	  dump ("rref", rr);
-	  dump ("q   ", q);
-	  dump ("qref", rq);
-	  abort ();
-	}
-      mini_random_div_op (OP_TDIV, MAXBITS, a, b, rq, rr);
-      mpz_tdiv_qr (q, r, a, b);
-      if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
-	{
-	  fprintf (stderr, "mpz_tdiv_qr failed:\n");
-	  dump ("a", a);
-	  dump ("b", b);
-	  dump ("r   ", r);
-	  dump ("rref", rr);
-	  dump ("q   ", q);
-	  dump ("qref", rq);
-	  abort ();
+	  static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV };
+	  static const char name[3] = { 'c', 'f', 't'};
+	  static div_func * const div [3] =
+	    {
+	      mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr
+	    };
+	  static div_ui_func  *div_ui[3] =
+	    {
+	      mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui
+	    };
+	  
+	  mini_random_div_op (ops[j], MAXBITS, a, b, rq, rr);
+	  div[j] (q, r, a, b);
+	  if (mpz_cmp (r, rr) || mpz_cmp (q, rq))
+	    {
+	      fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]);
+	      dump ("a", a);
+	      dump ("b", b);
+	      dump ("r   ", r);
+	      dump ("rref", rr);
+	      dump ("q   ", q);
+	      dump ("qref", rq);
+	      abort ();
+	    }
+	  if (mpz_fits_ulong_p (b))
+	    {
+	      mp_limb_t rl;
+	      rl = div_ui[j] (q, r, a, mpz_get_ui (b));
+


More information about the gmp-commit mailing list