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

mercurial at gmplib.org mercurial at gmplib.org
Thu Jan 5 15:14:44 CET 2012


details:   /var/hg/gmp-proj/mini-gmp/rev/9f9892577bc5
changeset: 48:9f9892577bc5
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Thu Jan 05 14:58:26 2012 +0100
description:
mpz_set_d, mpz_get_d: Don't depend on libm functions.

details:   /var/hg/gmp-proj/mini-gmp/rev/e0d62b4ac688
changeset: 49:e0d62b4ac688
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Thu Jan 05 14:58:57 2012 +0100
description:
Whitespace cleanup.

details:   /var/hg/gmp-proj/mini-gmp/rev/1d239774cf49
changeset: 50:1d239774cf49
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Thu Jan 05 15:14:35 2012 +0100
description:
Reordered functions for a bit better overall structure.

diffstat:

 mini-gmp.c |  626 +++++++++++++++++++++++++++++++-----------------------------
 1 files changed, 325 insertions(+), 301 deletions(-)

diffs (truncated from 878 to 300 lines):

diff -r d74bc57c9fa5 -r 1d239774cf49 mini-gmp.c
--- a/mini-gmp.c	Wed Jan 04 23:42:06 2012 +0100
+++ b/mini-gmp.c	Thu Jan 05 15:14:35 2012 +0100
@@ -40,7 +40,6 @@
 #include <assert.h>
 #include <ctype.h>
 #include <limits.h>
-#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -274,7 +273,7 @@
 }
 
 
-/* mpn interface */
+/* MPN interface */
 
 void
 mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
@@ -591,6 +590,8 @@
   return retval;
 }
 
+
+/* MPN division interface. */
 mp_limb_t
 mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
 {
@@ -717,7 +718,7 @@
 		   mp_srcptr dp, mp_size_t dn)
 {
   assert (dn > 0);
-  
+
   if (dn == 1)
     mpn_div_qr_1_invert (inv, dp[0]);
   else if (dn == 2)
@@ -816,7 +817,7 @@
   d1 = inv->d1;
   d0 = inv->d0;
   di = inv->di;
-  
+
   if (shift > 0)
     {
       tp = gmp_xalloc_limbs (nn);
@@ -952,7 +953,7 @@
 
       assert (inv->d1 == dp[dn-1]);
       assert (inv->d0 == dp[dn-2]);
-      
+
       mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di);
 
       if (shift > 0)
@@ -981,6 +982,8 @@
     free (tp);
 }
 
+
+/* MPN base conversion. */
 static unsigned
 mpn_base_power_of_two_p (unsigned b)
 {
@@ -1024,12 +1027,11 @@
 mp_bitcnt_t
 mpn_limb_size_in_base_2 (mp_limb_t u)
 {
-  /* FIXME: Use gmp_clz */
-  mp_bitcnt_t bits;
-  for (bits = 0; u > 0; bits++)
-    u >>= 1;
-
-  return bits;
+  unsigned shift;
+
+  assert (u > 0);
+  gmp_clz (shift, u);
+  return GMP_LIMB_BITS - shift;
 }
 
 static size_t
@@ -1237,7 +1239,7 @@
 }
 
 
-/* mpz interface */
+/* MPZ interface */
 void
 mpz_init (mpz_t r)
 {
@@ -1272,7 +1274,204 @@
 #define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc			\
 			  ? mpz_realloc(z,n)			\
 			  : (z)->_mp_d)
-
+
+/* MPZ assignment and basic conversions. */
+void
+mpz_set_si (mpz_t r, signed long int x)
+{
+  if (x > 0)
+    {
+      r->_mp_size = 1;
+      r->_mp_d[0] = x;
+    }
+  else if (x < 0)
+    {
+      r->_mp_size = -1;
+      r->_mp_d[0] = -x;
+    }
+  else
+    r->_mp_size = 0;
+}
+
+void
+mpz_set_ui (mpz_t r, unsigned long int x)
+{
+  if (x > 0)
+    {
+      r->_mp_size = 1;
+      r->_mp_d[0] = x;
+    }
+  else
+    r->_mp_size = 0;
+}
+
+void
+mpz_set (mpz_t r, const mpz_t x)
+{
+  /* Allow the NOP r == x */
+  if (r != x)
+    {
+      mp_size_t n;
+      mp_ptr rp;
+
+      n = GMP_ABS (x->_mp_size);
+      rp = MPZ_REALLOC (r, n);
+
+      mpn_copyi (rp, x->_mp_d, n);
+      r->_mp_size = x->_mp_size;
+    }
+}
+
+void
+mpz_init_set_si (mpz_t r, signed long int x)
+{
+  mpz_init (r);
+  mpz_set_si (r, x);
+}
+
+void
+mpz_init_set_ui (mpz_t r, unsigned long int x)
+{
+  mpz_init (r);
+  mpz_set_ui (r, x);
+}
+
+void
+mpz_init_set (mpz_t r, const mpz_t x)
+{
+  mpz_init (r);
+  mpz_set (r, x);
+}
+
+int
+mpz_fits_slong_p (const mpz_t u)
+{
+  mp_size_t us = u->_mp_size;
+
+  if (us == 0)
+    return 1;
+  else if (us == 1)
+    return u->_mp_d[0] < (GMP_LIMB_HIGHBIT / 2);
+  else if (us == -1)
+    return u->_mp_d[0] <= (GMP_LIMB_HIGHBIT / 2);
+  else
+    return 0;
+}
+
+int
+mpz_fits_ulong_p (const mpz_t u)
+{
+  mp_size_t us = u->_mp_size;
+
+  return us == 0 || us == 1;
+}
+
+long int
+mpz_get_si (const mpz_t u)
+{
+  mp_size_t us = u->_mp_size;
+
+  if (us > 0)
+    return (long) (u->_mp_d[0] & ~GMP_LIMB_HIGHBIT);
+  else if (us < 0)
+    return (long) (- u->_mp_d[0] | GMP_LIMB_HIGHBIT);
+  else
+    return 0;
+}
+
+unsigned long int
+mpz_get_ui (const mpz_t u)
+{
+  return u->_mp_size == 0 ? 0 : u->_mp_d[0];
+}
+
+
+/* Conversions and comparison to double. */
+void
+mpz_set_d (mpz_t r, double x)
+{
+  int sign;
+  mp_ptr rp;
+  mp_size_t rn, i;
+  double B;
+  double Bi;
+  mp_limb_t f;
+
+  /* x != x is true when x is a NaN, and x == x/2 is true when x is
+     zero or infinity. */
+  if (x == 0.0 || x != x || x == x/2)
+    {
+      r->_mp_size = 0;
+      return;
+    }
+
+  if (x < 0.0)
+    {
+      x = - x;
+      sign = 1;
+    }
+  else
+    sign = 0;
+
+  if (x < 1.0)
+    {
+      r->_mp_size = 0;
+      return;
+    }
+  B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+  Bi = 1.0 / B;
+  for (rn = 1; x >= B; rn++)
+    x *= Bi;
+
+  rp = MPZ_REALLOC (r, rn);
+
+  f = (mp_limb_t) x;
+  x -= f;
+  assert (x < 1.0);
+  rp[rn-1] = f;
+  for (i = rn-1; i-- > 0; )
+    {
+      x = B * x;
+      f = (mp_limb_t) x;
+      x -= f;
+      assert (x < 1.0);
+      rp[i] = f;
+    }
+
+  r->_mp_size = sign ? - rn : rn;
+}
+
+void
+mpz_init_set_d (mpz_t r, double x)
+{
+  mpz_init (r);
+  mpz_set_d (r, x);
+}
+
+double
+mpz_get_d (const mpz_t u)
+{
+  mp_size_t un;
+  double x;
+  double B = 2.0 * (double) GMP_LIMB_HIGHBIT;
+
+  un  = GMP_ABS (u->_mp_size);
+
+  if (un == 0)
+    return 0.0;
+
+  x = u->_mp_d[--un];
+  while (un > 0)
+    x = B*x + u->_mp_d[--un];
+
+  if (u->_mp_size < 0)
+    x = -x;
+
+  return x;
+}
+
+
+/* MPN comparisons and the like. */
 int
 mpz_sgn (const mpz_t u)
 {
@@ -1413,6 +1612,8 @@
   MP_PTR_SWAP (u->_mp_d, v->_mp_d);


More information about the gmp-commit mailing list