diff options
author | tege <tege@gmplib.org> | 2000-06-29 17:41:25 +0200 |
---|---|---|
committer | tege <tege@gmplib.org> | 2000-06-29 17:41:25 +0200 |
commit | bf8a7583b815d456dfd84be4582e251057990fb3 (patch) | |
tree | 85c01a06cf8f0321c3b0138de261f63a73793787 /mpf | |
parent | 428c82548bb8cd90bf9d02470e7520e2d441e57e (diff) | |
download | gmp-bf8a7583b815d456dfd84be4582e251057990fb3.tar.gz |
Streamline criterion for whether to use mpn_lshift or
mpn_rshift. Increase precision when exp is a multiple of
BITS_PER_MP_LIMB primarily to make exp==0 be a noop.
Diffstat (limited to 'mpf')
-rw-r--r-- | mpf/div_2exp.c | 33 | ||||
-rw-r--r-- | mpf/mul_2exp.c | 39 |
2 files changed, 41 insertions, 31 deletions
diff --git a/mpf/div_2exp.c b/mpf/div_2exp.c index 3964fa879..827d34262 100644 --- a/mpf/div_2exp.c +++ b/mpf/div_2exp.c @@ -51,38 +51,43 @@ mpf_div_2exp (r, u, exp) abs_usize = ABS (usize); up = u->_mp_d; - if (abs_usize > prec) - { - up += abs_usize - prec; - abs_usize = prec; - } - if (exp % BITS_PER_MP_LIMB == 0) { + prec++; /* retain more precision here as we don't need + to account for carry-out here */ + if (abs_usize > prec) + { + up += abs_usize - prec; + abs_usize = prec; + } if (rp != up) MPN_COPY_INCR (rp, up, abs_usize); r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB; } else { - /* Use mpn_lshift since mpn_rshift operates upwards, and we therefore - would clobber part of U before using that part, when R == U. */ mp_limb_t cy_limb; - if (rp < up) + mp_size_t adj; + if (abs_usize > prec) { + up += abs_usize - prec; + abs_usize = prec; + /* Use mpn_rshift since mpn_lshift operates downwards, and we + therefore would clobber part of U before using that part, in case + R is the same variable as U. */ cy_limb = mpn_rshift (rp + 1, up, abs_usize, exp % BITS_PER_MP_LIMB); rp[0] = cy_limb; - cy_limb = rp[abs_usize] != 0; + adj = rp[abs_usize] != 0; } else { - cy_limb = mpn_lshift (rp, up, abs_usize, -exp % BITS_PER_MP_LIMB); + cy_limb = mpn_lshift (rp, up, abs_usize, (-exp) % BITS_PER_MP_LIMB); rp[abs_usize] = cy_limb; - cy_limb = cy_limb != 0; + adj = cy_limb != 0; } - abs_usize += cy_limb; - r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB - 1 + cy_limb; + abs_usize += adj; + r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB - 1 + adj; } r->_mp_size = usize >= 0 ? abs_usize : -abs_usize; } diff --git a/mpf/mul_2exp.c b/mpf/mul_2exp.c index 5b7345866..6f9e1dc75 100644 --- a/mpf/mul_2exp.c +++ b/mpf/mul_2exp.c @@ -51,14 +51,15 @@ mpf_mul_2exp (r, u, exp) abs_usize = ABS (usize); up = u->_mp_d; - if (abs_usize > prec) - { - up += abs_usize - prec; - abs_usize = prec; - } - if (exp % BITS_PER_MP_LIMB == 0) { + prec++; /* retain more precision here as we don't need + to account for carry-out here */ + if (abs_usize > prec) + { + up += abs_usize - prec; + abs_usize = prec; + } if (rp != up) MPN_COPY_INCR (rp, up, abs_usize); r->_mp_exp = uexp + exp / BITS_PER_MP_LIMB; @@ -66,23 +67,27 @@ mpf_mul_2exp (r, u, exp) else { mp_limb_t cy_limb; - if (rp >= up) + mp_size_t adj; + if (abs_usize > prec) { - cy_limb = mpn_lshift (rp, up, abs_usize, exp % BITS_PER_MP_LIMB); - rp[abs_usize] = cy_limb; - cy_limb = cy_limb != 0; + up += abs_usize - prec; + abs_usize = prec; + /* Use mpn_rshift since mpn_lshift operates downwards, and we + therefore would clobber part of U before using that part, in case + R is the same variable as U. */ + cy_limb = mpn_rshift (rp + 1, up, abs_usize, (-exp) % BITS_PER_MP_LIMB); + rp[0] = cy_limb; + adj = rp[abs_usize] != 0; } else { - /* Use mpn_rshift since mpn_lshift operates downwards, and we - therefore would clobber part of U before using that part. */ - cy_limb = mpn_rshift (rp + 1, up, abs_usize, -exp % BITS_PER_MP_LIMB); - rp[0] = cy_limb; - cy_limb = rp[abs_usize] != 0; + cy_limb = mpn_lshift (rp, up, abs_usize, exp % BITS_PER_MP_LIMB); + rp[abs_usize] = cy_limb; + adj = cy_limb != 0; } - abs_usize += cy_limb; - r->_mp_exp = uexp + exp / BITS_PER_MP_LIMB + cy_limb; + abs_usize += adj; + r->_mp_exp = uexp + exp / BITS_PER_MP_LIMB + adj; } r->_mp_size = usize >= 0 ? abs_usize : -abs_usize; } |