diff options
author | Torbjorn Granlund <tege@gmplib.org> | 2012-01-07 13:22:49 +0100 |
---|---|---|
committer | Torbjorn Granlund <tege@gmplib.org> | 2012-01-07 13:22:49 +0100 |
commit | aeb18ea0095c9ba1055f93e14edfcd90e719a5e9 (patch) | |
tree | f2f515a746081abf41f6d6a7da5edf18b37920c5 /mpz/mul_2exp.c | |
parent | 8ca3c891cbba6a5dfa2a831e06b615378a3a382a (diff) | |
download | gmp-aeb18ea0095c9ba1055f93e14edfcd90e719a5e9.tar.gz |
Rewrite.
Diffstat (limited to 'mpz/mul_2exp.c')
-rw-r--r-- | mpz/mul_2exp.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/mpz/mul_2exp.c b/mpz/mul_2exp.c index a1521816e..4e1f4e6bd 100644 --- a/mpz/mul_2exp.c +++ b/mpz/mul_2exp.c @@ -1,6 +1,7 @@ /* mpz_mul_2exp -- Multiply a bignum by 2**CNT -Copyright 1991, 1993, 1994, 1996, 2001, 2002 Free Software Foundation, Inc. +Copyright 1991, 1993, 1994, 1996, 2001, 2002, 2012 Free Software Foundation, +Inc. This file is part of the GNU MP Library. @@ -21,47 +22,41 @@ along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ #include "gmp-impl.h" void -mpz_mul_2exp (mpz_ptr w, mpz_srcptr u, mp_bitcnt_t cnt) +mpz_mul_2exp (mpz_ptr r, mpz_srcptr u, mp_bitcnt_t cnt) { - mp_size_t usize = u->_mp_size; - mp_size_t abs_usize = ABS (usize); - mp_size_t wsize; + mp_size_t un, rn; mp_size_t limb_cnt; - mp_ptr wp; - mp_limb_t wlimb; - - if (usize == 0) - { - w->_mp_size = 0; - return; - } + mp_ptr rp; + mp_srcptr up; + mp_limb_t rlimb; + un = ABSIZ (u); limb_cnt = cnt / GMP_NUMB_BITS; - wsize = abs_usize + limb_cnt + 1; - if (w->_mp_alloc < wsize) - _mpz_realloc (w, wsize); - - wp = w->_mp_d; - wsize = abs_usize + limb_cnt; + rn = un + limb_cnt; - cnt %= GMP_NUMB_BITS; - if (cnt != 0) + if (un == 0) + rn = 0; + else { - wlimb = mpn_lshift (wp + limb_cnt, u->_mp_d, abs_usize, cnt); - if (wlimb != 0) + rp = MPZ_REALLOC (r, rn + 1); + up = PTR(u); + + cnt %= GMP_NUMB_BITS; + if (cnt != 0) { - wp[wsize] = wlimb; - wsize++; + rlimb = mpn_lshift (rp + limb_cnt, up, un, cnt); + rp[rn] = rlimb; + rn += (rlimb != 0); + } + else + { + MPN_COPY_DECR (rp + limb_cnt, up, un); } - } - else - { - MPN_COPY_DECR (wp + limb_cnt, u->_mp_d, abs_usize); - } - /* Zero all whole limbs at low end. Do it here and not before calling - mpn_lshift, not to lose for U == W. */ - MPN_ZERO (wp, limb_cnt); + /* Zero all whole limbs at low end. Do it here and not before calling + mpn_lshift, not to lose for U == R. */ + MPN_ZERO (rp, limb_cnt); + } - w->_mp_size = usize >= 0 ? wsize : -wsize; + SIZ(r) = SIZ(u) >= 0 ? rn : -rn; } |