[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