[Gmp-commit] /var/hg/gmp: mini-gmp: simplify mpz_rootrem, small correction in...

mercurial at gmplib.org mercurial at gmplib.org
Wed Apr 11 18:35:38 CEST 2012


details:   /var/hg/gmp/rev/718fff86cd74
changeset: 14807:718fff86cd74
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Wed Apr 11 18:35:16 2012 +0200
description:
mini-gmp: simplify mpz_rootrem, small correction in mpz_mul_ui.

diffstat:

 ChangeLog               |   3 ++-
 mini-gmp/mini-gmp.c     |  24 +++++++++++-------------
 mini-gmp/tests/t-root.c |   9 +++++++--
 3 files changed, 20 insertions(+), 16 deletions(-)

diffs (115 lines):

diff -r 3b4e2745b0de -r 718fff86cd74 ChangeLog
--- a/ChangeLog	Wed Apr 11 11:07:15 2012 +0200
+++ b/ChangeLog	Wed Apr 11 18:35:16 2012 +0200
@@ -3,9 +3,10 @@
 	* mini-gmp/mini-gmp.h (mpz_root, mpz_rootrem): define (correctly).
 	* mini-gmp/mini-gmp.c (mpz_rootrem): Extended code from _root.
 	(mpz_root): Use mpz_rootrem.
+	(mpz_mul_ui): Correctly handle negative operands.
 
 	* mini-gmp/tests/Makefile (CHECK_PROGRAMS): add t-root.
-	* mini-gmp/tests/t-root.c: New file
+	* mini-gmp/tests/t-root.c: New file.
 	* mini-gmp/tests/t-reuse.c: Enable root{,rem} tests.
 
 2012-04-10 Marco Bodrato <bodrato at mail.dm.unipi.it>
diff -r 3b4e2745b0de -r 718fff86cd74 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Wed Apr 11 11:07:15 2012 +0200
+++ b/mini-gmp/mini-gmp.c	Wed Apr 11 18:35:16 2012 +0200
@@ -1956,6 +1956,8 @@
   tp[un] = cy;
 
   t->_mp_size = un + (cy > 0);
+  if (u->_mp_size < 0)
+    t->_mp_size = - t->_mp_size;
 
   mpz_swap (r, t);
   mpz_clear (t);
@@ -3143,12 +3145,12 @@
   mpz_clear (e);
 }
 
-/* x=floor(y^(1/z)), r=y-x^z */
+/* x=trunc(y^(1/z)), r=y-x^z */
 void
 mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
 {
   int sgn;
-  mpz_t t, u, v, ty;
+  mpz_t t, u, v;
 
   sgn = y->_mp_size < 0;
   if (sgn && (z & 1) == 0)
@@ -3156,38 +3158,34 @@
   if (z == 0)
     gmp_die ("mpz_rootrem: Zeroth root.");
 
-  if (mpz_cmp_ui (y, 1) <= 0) {
+  if (mpz_cmpabs_ui (y, 1) <= 0) {
     mpz_set (x, y);
     if (r)
       r->_mp_size = 0;
     return;
   }
 
-  ty->_mp_size = GMP_ABS (y->_mp_size);
-  ty->_mp_d = y->_mp_d;
-
   mpz_init (t);
   mpz_init (v);
   mpz_init (u);
-  mpz_setbit (t, mpz_sizeinbase (ty, 2) / z + 1);
+  mpz_setbit (t, mpz_sizeinbase (y, 2) / z + 1);
+  if (sgn)
+    mpz_neg (t,t);
 
   do {
     mpz_set (u, t);
     mpz_pow_ui (t, u, z - 1);
-    mpz_tdiv_q (t, ty, t);
+    mpz_tdiv_q (t, y, t);
     mpz_mul_ui (v, u, z - 1);
     mpz_add (t, t, v);
     mpz_tdiv_q_ui (t, t, z);
-  } while (mpz_cmp (t, u) < 0);
+  } while (mpz_cmpabs (t, u) < 0);
 
   if (r) {
     mpz_pow_ui (t, u, z);
     mpz_sub (r, y, t);
   }
-  if (sgn)
-    mpz_neg (x, u);
-  else
-    mpz_set (x, u);
+  mpz_set (x, u);
   mpz_clear (u);
   mpz_clear (v);
   mpz_clear (t);
diff -r 3b4e2745b0de -r 718fff86cd74 mini-gmp/tests/t-root.c
--- a/mini-gmp/tests/t-root.c	Wed Apr 11 11:07:15 2012 +0200
+++ b/mini-gmp/tests/t-root.c	Wed Apr 11 18:35:16 2012 +0200
@@ -29,7 +29,10 @@
       mpz_clear (t);
       return 0;
     }
-  mpz_add_ui (t, s, 1);
+  if (mpz_sgn (s) > 0)
+    mpz_add_ui (t, s, 1);
+  else
+    mpz_sub_ui (t, s, 1);
   mpz_pow_ui (t, t, z);
   if (mpz_cmpabs (t, u) <= 0)
     {
@@ -58,8 +61,10 @@
   for (i = 0; i < COUNT; i++)
     {
       mini_rrandomb (u, MAXBITS);
-      mini_rrandomb (bs, 10);
+      mini_rrandomb (bs, 12);
       e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 2;
+      if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
+	mpz_neg (u, u);
       mpz_rootrem (s, r, u, e);
 
       if (!rootrem_valid_p (u, s, r, e))


More information about the gmp-commit mailing list