diff options
author | Torbjorn Granlund <tege@gmplib.org> | 2011-03-01 19:14:49 +0100 |
---|---|---|
committer | Torbjorn Granlund <tege@gmplib.org> | 2011-03-01 19:14:49 +0100 |
commit | 4a13a2fcdb18ec51a4ba871b6c29173df22e6eef (patch) | |
tree | bb1bf38662524416581ba2f8a9d25e743ecda0f5 /mpz/divegcd.c | |
parent | 5667f05683ef0faa033de1dd2aa2af42584c2f45 (diff) | |
download | gmp-4a13a2fcdb18ec51a4ba871b6c29173df22e6eef.tar.gz |
Rewrite, as per Marc Glisse's suggestion.
Diffstat (limited to 'mpz/divegcd.c')
-rw-r--r-- | mpz/divegcd.c | 100 |
1 files changed, 46 insertions, 54 deletions
diff --git a/mpz/divegcd.c b/mpz/divegcd.c index 49257aec2..c67e76972 100644 --- a/mpz/divegcd.c +++ b/mpz/divegcd.c @@ -49,62 +49,77 @@ static void mpz_divexact_by3 (mpz_ptr q, mpz_srcptr a) { mp_size_t size = SIZ(a); - if (size == 0) - { - SIZ(q) = 0; - return; - } - else - { - mp_size_t abs_size = ABS(size); - mp_ptr qp; + mp_size_t abs_size = ABS(size); + mp_ptr qp; - MPZ_REALLOC (q, abs_size); + MPZ_REALLOC (q, abs_size); - qp = PTR(q); - mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 3); + qp = PTR(q); + mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 3); - abs_size -= (qp[abs_size-1] == 0); - SIZ(q) = (size>0 ? abs_size : -abs_size); - } + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size>0 ? abs_size : -abs_size); } #endif + #if GMP_NUMB_BITS % 4 == 0 static void mpz_divexact_by5 (mpz_ptr q, mpz_srcptr a) { mp_size_t size = SIZ(a); - if (size == 0) - { - SIZ(q) = 0; - return; - } - else - { - mp_size_t abs_size = ABS(size); - mp_ptr qp; + mp_size_t abs_size = ABS(size); + mp_ptr qp; - MPZ_REALLOC (q, abs_size); + MPZ_REALLOC (q, abs_size); - qp = PTR(q); - mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 5); + qp = PTR(q); + mpn_bdiv_dbm1 (qp, PTR(a), abs_size, GMP_NUMB_MASK / 5); - abs_size -= (qp[abs_size-1] == 0); - SIZ(q) = (size>0 ? abs_size : -abs_size); - } + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size>0 ? abs_size : -abs_size); } #endif +static void +mpz_divexact_limb (mpz_ptr q, mpz_srcptr a, mp_limb_t d) +{ + mp_size_t size = SIZ(a); + mp_size_t abs_size = ABS(size); + mp_ptr qp; + + MPZ_REALLOC (q, abs_size); + + qp = PTR(q); + mpn_divexact_1 (qp, PTR(a), abs_size, d); + + abs_size -= (qp[abs_size-1] == 0); + SIZ(q) = (size>0 ? abs_size : -abs_size); +} + void mpz_divexact_gcd (mpz_ptr q, mpz_srcptr a, mpz_srcptr d) { ASSERT (mpz_sgn (d) > 0); + if (SIZ(a) == 0) + { + SIZ(q) = 0; + return; + } + if (SIZ(d) == 1) { mp_limb_t dl = PTR(d)[0]; int twos; + if ((dl & 1) == 0) + { + count_trailing_zeros (twos, dl); + dl >>= twos; + mpz_tdiv_q_2exp (q, a, twos); + a = q; + } + if (dl == 1) { if (q != a) @@ -126,30 +141,7 @@ mpz_divexact_gcd (mpz_ptr q, mpz_srcptr a, mpz_srcptr d) } #endif - count_trailing_zeros (twos, dl); - dl >>= twos; - mpz_tdiv_q_2exp (q, a, twos); - - if (dl == 1) - { - return; - } -#if GMP_NUMB_BITS % 2 == 0 - if (dl == 3) - { - mpz_divexact_by3 (q, q); - return; - } -#endif -#if GMP_NUMB_BITS % 4 == 0 - if (dl == 5) - { - mpz_divexact_by5 (q, q); - return; - } -#endif - - mpz_divexact_ui (q, q, dl); + mpz_divexact_limb (q, a, dl); return; } |