X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/75263f25a1ce8e7b38ad4bd61a9a893723ec1db3..1589affab225db500965e2cb869c534d6860e6bd:/mp-arith.c diff --git a/mp-arith.c b/mp-arith.c index 759056b..53584e7 100644 --- a/mp-arith.c +++ b/mp-arith.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: mp-arith.c,v 1.15 2002/10/19 17:56:50 mdw Exp $ + * $Id: mp-arith.c,v 1.17 2003/10/12 15:03:35 mdw Exp $ * * Basic arithmetic on multiprecision integers * @@ -30,6 +30,15 @@ /*----- Revision history --------------------------------------------------* * * $Log: mp-arith.c,v $ + * Revision 1.17 2003/10/12 15:03:35 mdw + * Merge fix from other branch. + * + * Revision 1.16.2.1 2003/06/10 13:21:10 mdw + * Fix bug dividing small things by large ones. + * + * Revision 1.16 2003/05/16 09:09:24 mdw + * Fix @mp_lsl2c@. Turns out to be surprisingly tricky. + * * Revision 1.15 2002/10/19 17:56:50 mdw * Fix bit operations. Test them (a bit) better. * @@ -91,13 +100,18 @@ /*----- Main code ---------------------------------------------------------*/ -/* --- @mp_lsl@, @mp_lsr@ --- * +/* --- @mp_lsl@, @mp_lslc@, @mp_lsr@ --- * * * Arguments: @mp *d@ = destination * @mp *a@ = source * @size_t n@ = number of bits to move * * Returns: Result, @a@ shifted left or right by @n@. + * + * Use: Bitwise shift operators. @mp_lslc@ fills the bits introduced + * on the right with ones instead of zeroes: it's used + * internally by @mp_lsl2c@, though it may be useful on its + * own. */ mp *mp_lsl(mp *d, mp *a, size_t n) @@ -109,6 +123,15 @@ mp *mp_lsl(mp *d, mp *a, size_t n) return (d); } +mp *mp_lslc(mp *d, mp *a, size_t n) +{ + MP_DEST(d, MP_LEN(a) + (n + MPW_BITS - 1) / MPW_BITS, a->f); + mpx_lslc(d->v, d->vl, a->v, a->vl, n); + d->f = a->f & (MP_NEG | MP_BURN); + MP_SHRINK(d); + return (d); +} + mp *mp_lsr(mp *d, mp *a, size_t n) { MP_DEST(d, MP_LEN(a), a->f); @@ -133,7 +156,7 @@ mp *mp_lsl2c(mp *d, mp *a, size_t n) if (!(a->f & MP_NEG)) return (mp_lsl(d, a, n)); d = mp_not2c(d, a); - d = mp_lsl(d, d, n); + d = mp_lslc(d, d, n); d = mp_not2c(d, d); return (d); } @@ -293,10 +316,10 @@ mp *mp_neg(mp *d, mp *a) MP_SHRINK(a); MP_COPY(a); - if (d) MP_DROP(d); - if (a->v == a->vl) { + if (d) + MP_DROP(d); + if (a->v == a->vl) return (a); - } MP_DEST(a, MP_LEN(a), a->f); a->f ^= MP_NEG; return (a); @@ -602,7 +625,7 @@ void mp_div(mp **qq, mp **rr, mp *a, mp *b) if (r) MP_DROP(r); r = a; - MP_DEST(r, MP_LEN(a) + 2, a->f | b->f); + MP_DEST(r, MAX(MP_LEN(a), MP_LEN(b)) + 2, a->f | b->f); /* --- Fix up the quotient too --- */