ref: 38a875c05a009fdd298e7a93086654c8b78b2f63
parent: 961b64f18bcd6f6280a79638fd0634ff915cc4aa
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Feb 4 19:21:59 EST 2015
Add more stdbigint test cases.
--- a/libstd/bigint.myr
+++ b/libstd/bigint.myr
@@ -63,9 +63,6 @@
*/
;;
-/* DEBUG */
-extern const put : (fmt : byte[:], ap : ... -> void)
-
const Base = 0x100000000ul
generic mkbigint = {v : @a::(integral,numeric)
@@ -99,14 +96,14 @@
const bigassign = {d, s
slfree(d.dig)
+ d# = s#
d.dig = sldup(s.dig)
- d.sign = s.sign
-> d
}
const bigmove = {d, s
slfree(d.dig)
- d.dig = s.dig
+ d# = s#
s.dig = [][:]
s.sign = 0
-> d
@@ -145,7 +142,13 @@
if base < 0 || base > 36
die("invalid base in bigbfmt\n")
- elif base == 0
+ ;;
+
+ if bigiszero(x)
+ n
+ ;;
+
+ if base == 0
b = mkbigint(10)
else
b = mkbigint(base)
@@ -445,11 +448,11 @@
Implements bigint division using Algorithm D from
Knuth: Seminumerical algorithms, Section 4.3.1.
*/
+ var m : int64, n : int64
var qhat, rhat, carry, shift
var x, y, z, w, p, t /* temporaries */
var b0, aj
var u, v
- var m : int64, n : int64
var i, j : int64
var q
@@ -537,17 +540,18 @@
;;
/* undo the biasing for remainder */
- bigshri(u, shift)
+ u = bigshri(u, shift)
-> (trim(q), trim(u))
}
/* computes b^e % m */
const bigmodpow = {base, exp, mod
- var r
+ var r, n
r = mkbigint(1)
+ n = 0
while !bigiszero(exp)
- if exp.dig[0] & 1 == 0
+ if exp.dig[0] & 1 != 0
bigmul(r, base)
bigmod(r, mod)
;;
--- a/test/data/stdbigint-expected
+++ b/test/data/stdbigint-expected
@@ -1,4 +1,9 @@
517347321949036993306
+0 == 0
1234567812346789666677778888 / 123456781234678966667777 == 10000
1208908684563961789813300 / 263951815549716 == 4580035496
5192296858534810493479828944327220 / 75557863709417659441940 == 68719476751
+75557863709417659441940 / 5192296858534810493479828944327220 == 0
+5192296858534810493479828944327220 % 75557863709417659441940 == 257025710597479990280
+(1 ^ 3) % 2 == 1
+(5192296858534810493479828944327220 ^ 75557863709417659441940) % 755578 == 49054
--- a/test/stdbigint.myr
+++ b/test/stdbigint.myr
@@ -15,8 +15,9 @@
const main = {
var a, b, c, d, e
- var buf : byte[4096], n
+ var buf : byte[64], n
+ /* a few combined ops */
a = std.mkbigint(1234)
b = std.mkbigint(0x7fffffff)
c = std.mkbigint(7919)
@@ -37,6 +38,8 @@
n = std.bigbfmt(buf[:], a, 0)
std.put("%s\n", buf[:n])
+ /* make sure we format '0' correctly */
+ run(std.mk(`Res (std.mk(`Val "0"))))
/* smoke test for division */
run(std.mk(`Res \
std.mk(`Div (\
@@ -50,11 +53,42 @@
std.mk(`Div (\
std.mk(`Val "5192296858534810493479828944327220"), \
std.mk(`Val "75557863709417659441940")))))
+ run(std.mk(`Res \
+ std.mk(`Div (\
+ std.mk(`Val "75557863709417659441940"), \
+ std.mk(`Val "5192296858534810493479828944327220")))))
+
+ /* smoke test for mod */
+ run(std.mk(`Res \
+ std.mk(`Mod (\
+ std.mk(`Val "5192296858534810493479828944327220"), \
+ std.mk(`Val "75557863709417659441940")))))
+
+ run(std.mk(`Res \
+ std.mk(`Modpow (\
+ std.mk(`Val "1"), \
+ std.mk(`Val "3"), \
+ std.mk(`Val "2")))))
+
+ run(std.mk(`Res \
+ std.mk(`Modpow (\
+ std.mk(`Val "5192296858534810493479828944327220"), \
+ std.mk(`Val "75557863709417659441940"), \
+ std.mk(`Val "755578")))))
+ /* BOTCHED
+ run(std.mk(`Res \
+ std.mk(`Modpow (\
+ std.mk(`Val "5192296858534810493479828944327220"), \
+ std.mk(`Val "755578"), \
+ std.mk(`Val "75557863709417659441940")))))
+ */
+
}
const run = {e : cmd#
- var buf : byte[4096]
- var v, n
+ var buf : byte[2048]
+ var a, b, c /* scratch vars */
+ var n /* buf len */
match e#
| `Add (x, y): -> binop("+", std.bigadd, x, y)
@@ -65,17 +99,23 @@
| `Shl (x, y): -> binop("<<", std.bigshl, x, y)
| `Shr (x, y): -> binop(">>", std.bigshr, x, y)
| `Val x:
- v = try(std.bigparse(x))
- n = std.bigbfmt(buf[:], v, 0)
+ a = try(std.bigparse(x))
+ n = std.bigbfmt(buf[:], a, 0)
std.put("%s", buf[:n])
- -> v
+ -> a
| `Res r:
- v = run(r)
- n = std.bigbfmt(buf[:], v, 0)
+ a = run(r)
+ n = std.bigbfmt(buf[:], a, 0)
std.put(" == %s\n", buf[:n])
- | `Modpow (x, y, m):
- n = std.bigbfmt(buf[:], std.bigmodpow(run(x), run(y), run(m)), 0)
- std.put("(%s ^ %s) % %s = %s\n", x, y, m, buf[:n])
+ -> a
+ | `Modpow (x, y, z):
+ std.put("(");
+ a = run(x)
+ std.put(" ^ ")
+ b = run(y)
+ std.put(") %% ")
+ c = run(z)
+ -> std.bigmodpow(a, b, c)
;;
}