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

mercurial at gmplib.org mercurial at gmplib.org
Sat Jan 7 14:51:03 CET 2012


details:   /var/hg/gmp-proj/mini-gmp/rev/b0d761983f79
changeset: 51:b0d761983f79
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 07 14:40:52 2012 +0100
description:
Implemented mpz_sqrt and mpz_ui_pow_ui.

details:   /var/hg/gmp-proj/mini-gmp/rev/b4a35239ce49
changeset: 52:b4a35239ce49
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 07 14:41:42 2012 +0100
description:
mpz_set_d: Use *0.5 rather than /2.

details:   /var/hg/gmp-proj/mini-gmp/rev/b8e2f8a30856
changeset: 53:b8e2f8a30856
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Sat Jan 07 14:50:51 2012 +0100
description:
>From Torbj?rn: Implemented mpz_tdiv_q_2exp and mpz_out_str.

diffstat:

 mini-gmp.c |  93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 mini-gmp.h |   8 +++++
 2 files changed, 91 insertions(+), 10 deletions(-)

diffs (177 lines):

diff -r 1d239774cf49 -r b8e2f8a30856 mini-gmp.c
--- a/mini-gmp.c	Thu Jan 05 15:14:35 2012 +0100
+++ b/mini-gmp.c	Sat Jan 07 14:50:51 2012 +0100
@@ -37,6 +37,12 @@
      mpz_lcm_ui
      mpz_popcount
  */
+/* Missing functions for gmp/gen-bases.c:
+
+     mpz_out_str
+     mpz_tdiv_q_2exp
+*/
+
 #include <assert.h>
 #include <ctype.h>
 #include <limits.h>
@@ -1397,9 +1403,9 @@
   double Bi;
   mp_limb_t f;
 
-  /* x != x is true when x is a NaN, and x == x/2 is true when x is
+  /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is
      zero or infinity. */
-  if (x == 0.0 || x != x || x == x/2)
+  if (x == 0.0 || x != x || x == x * 0.5)
     {
       r->_mp_size = 0;
       return;
@@ -2062,6 +2068,37 @@
 }
 
 void
+mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
+{
+  mp_size_t un, rn;
+  mp_size_t limb_cnt;
+  mp_ptr rp;
+
+  un = u->_mp_size;
+  limb_cnt = cnt / GMP_LIMB_BITS;
+  rn = GMP_ABS (un) - limb_cnt;
+  if (rn <= 0)
+    rn = 0;
+  else
+    {
+      rp = MPZ_REALLOC (r, rn);
+
+      cnt %= GMP_LIMB_BITS;
+      if (cnt != 0)
+	{
+	  mpn_rshift (rp, u->_mp_d + limb_cnt, rn, cnt);
+	  rn -= rp[rn - 1] == 0;
+	}
+      else
+	{
+	  mpn_copyi (rp, u->_mp_d + limb_cnt, rn);
+	}
+    }
+
+  r->_mp_size = un >= 0 ? rn : -rn;
+}
+
+void
 mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d)
 {
   mpz_div_qr (q, NULL, n, d, DIV_EXACT);
@@ -2552,9 +2589,9 @@
 }
 
 
-/* Higher level operations (sqrt and powm) */
-
-/* Compute s = floor(sqrt(u)) and r = u - s^2 */
+/* Higher level operations (sqrt and pow) */
+
+/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */
 void
 mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
 {
@@ -2597,12 +2634,15 @@
   mpz_sub_ui (x, x, 1);
   assert (x->_mp_size > 0);
 
-  mpz_sub_ui (dx, dx, 1);
-  mpz_sub (t, dx, t);
-  assert (t->_mp_size >= 0);
-
+  if (r)
+    {
+      mpz_sub_ui (dx, dx, 1);
+      mpz_sub (t, dx, t);
+      assert (t->_mp_size >= 0);
+
+      mpz_swap (t, r);
+    }
   mpz_swap (s, x);
-  mpz_swap (t, r);
 
   mpz_clear (x);
   mpz_clear (t);
@@ -2611,6 +2651,26 @@
 }
 
 void
+mpz_sqrt (mpz_t s, const mpz_t u)
+{
+  mpz_sqrtrem (s, NULL, u);
+}
+
+void
+mpz_ui_pow_ui (mpz_t r, unsigned long b, unsigned long e)
+{
+  mp_limb_t bit;
+  mpz_set_ui (r, 1);
+
+  for (bit = GMP_LIMB_HIGHBIT; bit > 0; bit >>= 1)
+    {
+      mpz_mul (r, r, r);
+      if (e & bit)
+	mpz_mul_ui (r, r, b);
+    }
+}
+
+void
 mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
 {
   mpz_t tr;
@@ -3295,3 +3355,16 @@
 
   return 0;
 }
+
+size_t
+mpz_out_str (FILE *stream, int base, const mpz_t x)
+{
+  char *str;
+  size_t len;
+
+  str = mpz_get_str (NULL, base, x);
+  len = strlen (str);
+  len = fwrite (str, 1, len, stream);
+  free (str);
+  return len;
+}
diff -r 1d239774cf49 -r b8e2f8a30856 mini-gmp.h
--- a/mini-gmp.h	Thu Jan 05 15:14:35 2012 +0100
+++ b/mini-gmp.h	Sat Jan 07 14:50:51 2012 +0100
@@ -117,6 +117,8 @@
 void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t);
 void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t);
 
+void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
+
 void mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d);
 
 unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
@@ -137,7 +139,9 @@
 int mpz_invert (mpz_t, const mpz_t, const mpz_t);
 
 void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t);
+void mpz_sqrt (mpz_t, const mpz_t);
 
+void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long);
 void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t);
 
 int mpz_tstbit (const mpz_t, mp_bitcnt_t);
@@ -170,6 +174,10 @@
 char *mpz_get_str (char *, int, const mpz_t);
 int mpz_set_str (mpz_t, const char *, int);
 
+#if defined (FILE)  
+size_t mpz_out_str (FILE *, int, const mpz_t);
+#endif
+
 #if defined (__cplusplus)
 }
 #endif


More information about the gmp-commit mailing list