[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