X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/043613346cc5a0a99ad54781212bf7fd2c62c415..dfa4e2cef990e26f06f4aefe7ee2981040dd0d2d:/mpmul.c diff --git a/mpmul.c b/mpmul.c index 46f7b72..e5d6a4a 100644 --- a/mpmul.c +++ b/mpmul.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: mpmul.c,v 1.1 2000/07/01 11:21:39 mdw Exp $ + * $Id: mpmul.c,v 1.2 2000/07/09 21:31:10 mdw Exp $ * * Multiply many small numbers together * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: mpmul.c,v $ + * Revision 1.2 2000/07/09 21:31:10 mdw + * Fix bug, and add a test rig. + * * Revision 1.1 2000/07/01 11:21:39 mdw * New interface for computing products of many (small) integers. * @@ -86,14 +89,14 @@ void mpmul_add(mpmul *b, mp *x) } if (i > HWM) { - while (i > LWM) { + while (i > LWM || (i > 0 && MP_LEN(b->v[i - 1]) <= MP_LEN(x))) { i--; x = mp_mul(x, x, b->v[i]); MP_DROP(b->v[i]); } } - b->v[i] = x; + b->v[i++] = x; b->i = i; } @@ -142,8 +145,46 @@ mp *mp_factorial(unsigned long i) x = mp_fromulong(x, j); mpmul_add(&b, x); } - mp_drop(x); + if (x) + mp_drop(x); return (mpmul_done(&b)); } +/*----- Test rig ----------------------------------------------------------*/ + +#ifdef TEST_RIG + +#include + +static int vfact(dstr *v) +{ + unsigned long x = *(unsigned long *)v[0].buf; + mp *fx = *(mp **)v[1].buf; + mp *y = mp_factorial(x); + int ok = 1; + if (MP_CMP(fx, !=, y)) { + fprintf(stderr, "factorial failed\n"); + MP_FPRINTF(stderr, (stderr, "%lu! = ", x), fx); + MP_EPRINT("result", y); + ok = 0; + } + mp_drop(fx); + mp_drop(y); + assert(mparena_count(MPARENA_GLOBAL) == 0); + return (ok); +} + +static test_chunk tests[] = { + { "factorial", vfact, { &type_ulong, &type_mp, 0 } }, + { 0, 0, { 0 } } +}; + +int main(int argc, char *argv[]) +{ + test_run(argc, argv, tests, SRCDIR "/tests/mp"); + return (0); +} + +#endif + /*----- That's all, folks -------------------------------------------------*/