freebn(modulus);
freebn(expected);
freebn(answer);
+ } else if (!strcmp(buf, "divmod")) {
+ Bignum n, d, expect_q, expect_r, answer_q, answer_r;
+ int fail;
+
+ if (ptrnum != 4) {
+ printf("%d: divmod with %d parameters, expected 4\n", line, ptrnum);
+ exit(1);
+ }
+
+ n = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);
+ d = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);
+ expect_q = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);
+ expect_r = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);
+ answer_q = bigdiv(n, d);
+ answer_r = bigmod(n, d);
+
+ fail = FALSE;
+ if (bignum_cmp(expect_q, answer_q) != 0) {
+ char *as = bignum_decimal(n);
+ char *bs = bignum_decimal(d);
+ char *cs = bignum_decimal(answer_q);
+ char *ds = bignum_decimal(expect_q);
+
+ printf("%d: fail: %s / %s gave %s expected %s\n",
+ line, as, bs, cs, ds);
+ fail = TRUE;
+
+ sfree(as);
+ sfree(bs);
+ sfree(cs);
+ sfree(ds);
+ }
+ if (bignum_cmp(expect_r, answer_r) != 0) {
+ char *as = bignum_decimal(n);
+ char *bs = bignum_decimal(d);
+ char *cs = bignum_decimal(answer_r);
+ char *ds = bignum_decimal(expect_r);
+
+ printf("%d: fail: %s mod %s gave %s expected %s\n",
+ line, as, bs, cs, ds);
+ fail = TRUE;
+
+ sfree(as);
+ sfree(bs);
+ sfree(cs);
+ sfree(ds);
+ }
+
+ freebn(n);
+ freebn(d);
+ freebn(expect_q);
+ freebn(expect_r);
+ freebn(answer_q);
+ freebn(answer_r);
+
+ if (fail)
+ fails++;
+ else
+ passes++;
} else {
printf("%d: unrecognised test keyword: '%s'\n", line, buf);
exit(1);
a, b, p = findprod((1<<i)+1, +1, (i, i+1))
print "mul", hexstr(a), hexstr(b), hexstr(p)
+# Bare tests of division/modulo.
+prefixes = [2**63, int(2**63.5), 2**64-1]
+for nsize in range(20, 200):
+ for dsize in range(20, 200):
+ for dprefix in prefixes:
+ d = sqrt(3<<(2*dsize)) + (dprefix<<dsize)
+ for nprefix in prefixes:
+ nbase = sqrt(3<<(2*nsize)) + (nprefix<<nsize)
+ for modulus in sorted({-1, 0, +1, d/2, nbase % d}):
+ n = nbase - (nbase % d) + modulus
+ if n < 0:
+ n += d
+ assert n >= 0
+ print "divmod", hexstr(n), hexstr(d), hexstr(n/d), hexstr(n%d)
+
# Simple tests of modmul.
for ai in range(20, 200, 60):
a = sqrt(3<<(2*ai-1))