X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ce76ff166af224efbeadc7beaa6fdfd4b222c63b..2685767a6125c1620719c7de6234aedf41857b7e:/mpx.c diff --git a/mpx.c b/mpx.c index 7f0b25a..f89a89b 100644 --- a/mpx.c +++ b/mpx.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: mpx.c,v 1.8 2000/06/25 12:59:02 mdw Exp $ + * $Id: mpx.c,v 1.11 2001/04/03 19:36:05 mdw Exp $ * * Low-level multiprecision arithmetic * @@ -30,6 +30,15 @@ /*----- Revision history --------------------------------------------------* * * $Log: mpx.c,v $ + * Revision 1.11 2001/04/03 19:36:05 mdw + * Add some simple bitwise operations so that Perl can use them. + * + * Revision 1.10 2000/10/08 12:06:12 mdw + * Provide @mpx_ueq@ for rapidly testing equality of two integers. + * + * Revision 1.9 2000/06/26 07:52:50 mdw + * Portability fix for the bug fix. + * * Revision 1.8 2000/06/25 12:59:02 mdw * (mpx_udiv): Fix bug in quotient digit estimation. * @@ -394,6 +403,50 @@ void mpx_lsr(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, size_t n) done:; } +/*----- Bitwise operations ------------------------------------------------*/ + +/* --- @mpx_and@, @mpx_or@, @mpx_xor@, @mpx_not@ --- * + * + * Arguments: @mpw *dv, *dvl@ = destination vector + * @const mpw *av, *avl@ = first source vector + * @const mpw *bv, *bvl@ = second source vector + * + * Returns: --- + * + * Use; Does the obvious bitwise operations. + */ + +#define MPX_BITBINOP(name, op) \ + \ +void mpx_##name(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, \ + const mpw *bv, const mpw *bvl) \ +{ \ + MPX_SHRINK(av, avl); \ + MPX_SHRINK(bv, bvl); \ + \ + while (dv < dvl) { \ + mpw a, b; \ + a = (av < avl) ? *av++ : 0; \ + b = (bv < bvl) ? *bv++ : 0; \ + *dv++ = a op b; \ + } \ +} + +MPX_BITBINOP(and, &) +MPX_BITBINOP(or, |) +MPX_BITBINOP(xor, ^) + +void mpx_not(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl) +{ + MPX_SHRINK(av, avl); + + while (dv < dvl) { + mpw a; + a = (av < avl) ? *av++ : 0; + *dv++ = ~a; + } +} + /*----- Unsigned arithmetic -----------------------------------------------*/ /* --- @mpx_2c@ --- * @@ -420,6 +473,29 @@ void mpx_2c(mpw *dv, mpw *dvl, const mpw *v, const mpw *vl) MPX_UADDN(dv, dvl, 1); } +/* --- @mpx_ueq@ --- * + * + * Arguments: @const mpw *av, *avl@ = first argument vector base and limit + * @const mpw *bv, *bvl@ = second argument vector base and limit + * + * Returns: Nonzero if the two vectors are equal. + * + * Use: Performs an unsigned integer test for equality. + */ + +int mpx_ueq(const mpw *av, const mpw *avl, const mpw *bv, const mpw *bvl) +{ + MPX_SHRINK(av, avl); + MPX_SHRINK(bv, bvl); + if (avl - av != bvl - bv) + return (0); + while (av < avl) { + if (*av++ != *bv++) + return (0); + } + return (1); +} + /* --- @mpx_ucmp@ --- * * * Arguments: @const mpw *av, *avl@ = first argument vector base and limit @@ -450,7 +526,7 @@ int mpx_ucmp(const mpw *av, const mpw *avl, const mpw *bv, const mpw *bvl) } return (0); } - + /* --- @mpx_uadd@ --- * * * Arguments: @mpw *dv, *dvl@ = destination vector base and limit @@ -839,7 +915,7 @@ void mpx_udiv(mpw *qv, mpw *qvl, mpw *rv, mpw *rvl, yh -= d; if (yl < dd) yh--; - yl -= dd; + yl = MPW(yl - dd); } } @@ -1067,7 +1143,7 @@ static int lsl(dstr *v) ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS); mpx_lsl(d, dl, a, al, n); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** lsl(%i) failed\n", n); dumpmp(" a", a, al); dumpmp("expected", c, cl); @@ -1092,7 +1168,7 @@ static int lsr(dstr *v) ALLOC(d, dl, al - a + (n + MPW_BITS - 1) / MPW_BITS + 1); mpx_lsr(d, dl, a, al, n); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** lsr(%i) failed\n", n); dumpmp(" a", a, al); dumpmp("expected", c, cl); @@ -1118,7 +1194,7 @@ static int uadd(dstr *v) ALLOC(d, dl, MAX(al - a, bl - b) + 1); mpx_uadd(d, dl, a, al, b, bl); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** uadd failed\n"); dumpmp(" a", a, al); dumpmp(" b", b, bl); @@ -1145,7 +1221,7 @@ static int usub(dstr *v) ALLOC(d, dl, al - a); mpx_usub(d, dl, a, al, b, bl); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** usub failed\n"); dumpmp(" a", a, al); dumpmp(" b", b, bl); @@ -1172,7 +1248,7 @@ static int umul(dstr *v) ALLOC(d, dl, (al - a) + (bl - b)); mpx_umul(d, dl, a, al, b, bl); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** umul failed\n"); dumpmp(" a", a, al); dumpmp(" b", b, bl); @@ -1197,7 +1273,7 @@ static int usqr(dstr *v) ALLOC(d, dl, 2 * (al - a)); mpx_usqr(d, dl, a, al); - if (MPX_UCMP(d, dl, !=, c, cl)) { + if (!mpx_ueq(d, dl, c, cl)) { fprintf(stderr, "\n*** usqr failed\n"); dumpmp(" a", a, al); dumpmp("expected", c, cl); @@ -1227,8 +1303,8 @@ static int udiv(dstr *v) ALLOC(s, sl, (bl - b) + 1); mpx_udiv(qq, qql, a, al, b, bl, s, sl); - if (MPX_UCMP(qq, qql, !=, q, ql) || - MPX_UCMP(a, al, !=, r, rl)) { + if (!mpx_ueq(qq, qql, q, ql) || + !mpx_ueq(a, al, r, rl)) { fprintf(stderr, "\n*** udiv failed\n"); dumpmp(" divisor", b, bl); dumpmp("expect r", r, rl); @@ -1260,7 +1336,6 @@ int main(int argc, char *argv[]) return (0); } - #endif /*----- That's all, folks -------------------------------------------------*/