summaryrefslogtreecommitdiff
path: root/mini-gmp
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2012-04-11 18:35:16 +0200
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2012-04-11 18:35:16 +0200
commitd3ea439d67126c6163ab13b1ddd592355b1e45cf (patch)
tree2d3262c314651b32296e77cb6d7f23ba6ad82fef /mini-gmp
parentb1fc41ff98dd808a66ae902ddeea7b2b54228481 (diff)
downloadgmp-d3ea439d67126c6163ab13b1ddd592355b1e45cf.tar.gz
mini-gmp: simplify mpz_rootrem, small correction in mpz_mul_ui.
Diffstat (limited to 'mini-gmp')
-rw-r--r--mini-gmp/mini-gmp.c24
-rw-r--r--mini-gmp/tests/t-root.c9
2 files changed, 18 insertions, 15 deletions
diff --git a/mini-gmp/mini-gmp.c b/mini-gmp/mini-gmp.c
index faff73ca7..d7ab53d8a 100644
--- a/mini-gmp/mini-gmp.c
+++ b/mini-gmp/mini-gmp.c
@@ -1956,6 +1956,8 @@ mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v)
tp[un] = cy;
t->_mp_size = un + (cy > 0);
+ if (u->_mp_size < 0)
+ t->_mp_size = - t->_mp_size;
mpz_swap (r, t);
mpz_clear (t);
@@ -3143,12 +3145,12 @@ mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m)
mpz_clear (e);
}
-/* x=floor(y^(1/z)), r=y-x^z */
+/* x=trunc(y^(1/z)), r=y-x^z */
void
mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
{
int sgn;
- mpz_t t, u, v, ty;
+ mpz_t t, u, v;
sgn = y->_mp_size < 0;
if (sgn && (z & 1) == 0)
@@ -3156,38 +3158,34 @@ mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
if (z == 0)
gmp_die ("mpz_rootrem: Zeroth root.");
- if (mpz_cmp_ui (y, 1) <= 0) {
+ if (mpz_cmpabs_ui (y, 1) <= 0) {
mpz_set (x, y);
if (r)
r->_mp_size = 0;
return;
}
- ty->_mp_size = GMP_ABS (y->_mp_size);
- ty->_mp_d = y->_mp_d;
-
mpz_init (t);
mpz_init (v);
mpz_init (u);
- mpz_setbit (t, mpz_sizeinbase (ty, 2) / z + 1);
+ 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, ty, t);
+ 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_cmp (t, u) < 0);
+ } while (mpz_cmpabs (t, u) < 0);
if (r) {
mpz_pow_ui (t, u, z);
mpz_sub (r, y, t);
}
- if (sgn)
- mpz_neg (x, u);
- else
- mpz_set (x, u);
+ mpz_set (x, u);
mpz_clear (u);
mpz_clear (v);
mpz_clear (t);
diff --git a/mini-gmp/tests/t-root.c b/mini-gmp/tests/t-root.c
index 2fdb1b4a2..a653a104f 100644
--- a/mini-gmp/tests/t-root.c
+++ b/mini-gmp/tests/t-root.c
@@ -29,7 +29,10 @@ rootrem_valid_p (const mpz_t u, const mpz_t s, const mpz_t r, unsigned long z)
mpz_clear (t);
return 0;
}
- mpz_add_ui (t, s, 1);
+ if (mpz_sgn (s) > 0)
+ mpz_add_ui (t, s, 1);
+ else
+ mpz_sub_ui (t, s, 1);
mpz_pow_ui (t, t, z);
if (mpz_cmpabs (t, u) <= 0)
{
@@ -58,8 +61,10 @@ main (int argc, char **argv)
for (i = 0; i < COUNT; i++)
{
mini_rrandomb (u, MAXBITS);
- mini_rrandomb (bs, 10);
+ mini_rrandomb (bs, 12);
e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 2;
+ if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
+ mpz_neg (u, u);
mpz_rootrem (s, r, u, e);
if (!rootrem_valid_p (u, s, r, e))