[Gmp-commit] /var/hg/gmp: mini-gmp/mini-gmp.c: merge mpz_rootrem and mpz_sqrt...
mercurial at gmplib.org
mercurial at gmplib.org
Wed May 9 05:50:34 CEST 2012
details: /var/hg/gmp/rev/f518302fa030
changeset: 14955:f518302fa030
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Wed May 09 05:50:26 2012 +0200
description:
mini-gmp/mini-gmp.c: merge mpz_rootrem and mpz_sqrtrem.
diffstat:
ChangeLog | 4 +
mini-gmp/mini-gmp.c | 122 +++++++++++++++++----------------------------------
2 files changed, 45 insertions(+), 81 deletions(-)
diffs (172 lines):
diff -r 9bf744339682 -r f518302fa030 ChangeLog
--- a/ChangeLog Tue May 08 14:48:22 2012 +0200
+++ b/ChangeLog Wed May 09 05:50:26 2012 +0200
@@ -1,3 +1,7 @@
+2012-05-09 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+ * mini-gmp/mini-gmp.c: merge mpz_rootrem and mpz_sqrtrem.
+
2012-05-08 Torbjorn Granlund <tege at gmplib.org>
* mpn/minithres/gmp-mparam.h (REDC_1_TO_REDC_N_THRESHOLD): Up to 9, for
diff -r 9bf744339682 -r f518302fa030 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c Tue May 08 14:48:22 2012 +0200
+++ b/mini-gmp/mini-gmp.c Wed May 09 05:50:26 2012 +0200
@@ -2942,72 +2942,6 @@
/* Higher level operations (sqrt, pow and root) */
-/* 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)
-{
- mpz_t x, t, dx, q;
-
- if (u->_mp_size < 0)
- gmp_die ("mpz_sqrtrem: Negative argument.");
- if (u->_mp_size == 0)
- {
- mpz_set_ui (s, 0);
- if (r)
- mpz_set_ui (r, 0);
- return;
- }
-
- mpz_init (x);
- mpz_init (t);
- mpz_init (dx);
- mpz_init (q);
-
- /* Make x > sqrt(a). This will be invariant through the loop. */
- mpz_setbit (x, (mpz_sizeinbase (u, 2) + 1) / 2);
-
- for (;;)
- {
- /* Compute x^2 - u */
- mpz_mul (t, x, x);
- mpz_sub (t, t, u);
- assert (t->_mp_size > 0);
-
- mpz_mul_2exp (dx, x, 1);
- mpz_tdiv_q (q, t, dx);
- if (q->_mp_size == 0)
- break;
- mpz_sub (x, x, q);
- assert (x->_mp_size > 0);
- }
- /* We have 0 < u - x^2 < 2x, which implies that sqrt(a) < x < 1 +
- sqrt(1+a), and x-1 = floor(sqrt(a)). Then r = a - (x-1)^2 = 2x -
- 1 - t. */
- mpz_sub_ui (x, x, 1);
- assert (x->_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_clear (x);
- mpz_clear (t);
- mpz_clear (dx);
- mpz_clear (q);
-}
-
-void
-mpz_sqrt (mpz_t s, const mpz_t u)
-{
- mpz_sqrtrem (s, NULL, u);
-}
-
void
mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e)
{
@@ -3150,7 +3084,7 @@
mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
{
int sgn;
- mpz_t t, u, v;
+ mpz_t t, u;
sgn = y->_mp_size < 0;
if (sgn && (z & 1) == 0)
@@ -3166,28 +3100,41 @@
}
mpz_init (t);
- mpz_init (v);
mpz_init (u);
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, y, t);
- mpz_mul_ui (v, u, z - 1);
- mpz_add (t, t, v);
- mpz_tdiv_q_ui (t, t, z);
- } while (mpz_cmpabs (t, u) < 0);
+
+ if (z == 2) /* simplify sqrt loop: z-1 == 1 */
+ do {
+ mpz_swap (u, t); /* u = x */
+ mpz_tdiv_q (t, y, u); /* t = y/x */
+ mpz_add (t, t, u); /* t = y/x + x */
+ mpz_tdiv_q_2exp (t, t, 1); /* x' = (y/x + x)/2 */
+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
+ else /* z != 2 */ {
+ mpz_t v;
+
+ mpz_init (v);
+ if (sgn)
+ mpz_neg (t,t);
+
+ do {
+ mpz_swap (u, t); /* u = x */
+ mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */
+ mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */
+ mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */
+ mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */
+ mpz_tdiv_q_ui (t, t, z); /* x' = (y/x^(z-1) + x*(z-1))/z */
+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
+
+ mpz_clear (v);
+ }
if (r) {
mpz_pow_ui (t, u, z);
mpz_sub (r, y, t);
}
- mpz_set (x, u);
+ mpz_swap (x, u);
mpz_clear (u);
- mpz_clear (v);
mpz_clear (t);
}
@@ -3205,6 +3152,19 @@
return res;
}
+/* 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)
+{
+ mpz_rootrem (s, r, u, 2);
+}
+
+void
+mpz_sqrt (mpz_t s, const mpz_t u)
+{
+ mpz_rootrem (s, NULL, u, 2);
+}
+
/* Combinatorics */
More information about the gmp-commit
mailing list