diff options
author | Damien George <damien.p.george@gmail.com> | 2014-05-13 22:58:00 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-05-13 22:58:00 +0100 |
commit | 51fab28e94fa914fb4564c9316eaa4dfe5567217 (patch) | |
tree | 03a765874e69ef9608624d5b395c3789518cf3ca | |
parent | f6e430f77fd06899e88d04243f0f29fe1d7ae42e (diff) | |
download | micropython-51fab28e94fa914fb4564c9316eaa4dfe5567217.tar.gz micropython-51fab28e94fa914fb4564c9316eaa4dfe5567217.zip |
py: Improve mpz_and function.
This should now have correct (and optimal) behaviour.
-rw-r--r-- | py/mpz.c | 11 |
1 files changed, 5 insertions, 6 deletions
@@ -207,17 +207,15 @@ STATIC uint mpn_sub(mpz_dig_t *idig, const mpz_dig_t *jdig, uint jlen, const mpz STATIC uint mpn_and(mpz_dig_t *idig, const mpz_dig_t *jdig, uint jlen, const mpz_dig_t *kdig, uint klen) { mpz_dig_t *oidig = idig; - jlen -= klen; - for (; klen > 0; --klen, ++idig, ++jdig, ++kdig) { *idig = *jdig & *kdig; } // remove trailing zeros - for (; idig > oidig && *idig == 0; --idig) { + for (--idig; idig >= oidig && *idig == 0; --idig) { } - return idig - oidig; + return idig + 1 - oidig; } /* computes i = j | k @@ -898,14 +896,15 @@ void mpz_sub_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) { can have dest, lhs, rhs the same */ void mpz_and_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) { - if (mpn_cmp(lhs->dig, lhs->len, rhs->dig, rhs->len) < 0) { + // make sure lhs has the most digits + if (lhs->len < rhs->len) { const mpz_t *temp = lhs; lhs = rhs; rhs = temp; } if (lhs->neg == rhs->neg) { - mpz_need_dig(dest, lhs->len); + mpz_need_dig(dest, rhs->len); dest->len = mpn_and(dest->dig, lhs->dig, lhs->len, rhs->dig, rhs->len); } else { mpz_need_dig(dest, lhs->len); |