diff options
author | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2012-04-11 18:35:16 +0200 |
---|---|---|
committer | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2012-04-11 18:35:16 +0200 |
commit | d3ea439d67126c6163ab13b1ddd592355b1e45cf (patch) | |
tree | 2d3262c314651b32296e77cb6d7f23ba6ad82fef /mini-gmp | |
parent | b1fc41ff98dd808a66ae902ddeea7b2b54228481 (diff) | |
download | gmp-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.c | 24 | ||||
-rw-r--r-- | mini-gmp/tests/t-root.c | 9 |
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)) |