summaryrefslogtreecommitdiff
path: root/libstd/bigint.myr
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-01-23 02:52:56 -0500
committerOri Bernstein <ori@eigenstate.org>2014-01-23 02:52:56 -0500
commitc98dd1239d76a56d36ce6511239ccfce2b5c6e43 (patch)
treede4a1fb3b105b587a6df1b0a0c4b9ea97d3f59a4 /libstd/bigint.myr
parent33191432d1d295d78a1c5638de7a9d9fc0ea97e4 (diff)
downloadmc-c98dd1239d76a56d36ce6511239ccfce2b5c6e43.tar.gz
Handle zeros correctly in bigint.myr
Diffstat (limited to 'libstd/bigint.myr')
-rw-r--r--libstd/bigint.myr42
1 files changed, 29 insertions, 13 deletions
diff --git a/libstd/bigint.myr b/libstd/bigint.myr
index ebf5c5e..a65d708 100644
--- a/libstd/bigint.myr
+++ b/libstd/bigint.myr
@@ -23,6 +23,7 @@ pkg std =
const mkbigint : (v : int32 -> bigint#)
const bigfree : (a : bigint# -> void)
const bigdup : (a : bigint# -> bigint#)
+ const bigassign : (d : bigint#, s : bigint# -> bigint#)
const bigparse : (s : byte[:] -> option(bigint#))
const bigfmt : (b : byte[:], a : bigint# -> size)
@@ -70,14 +71,17 @@ const bigfree = {a
}
const bigdup = {a
- var v
+ -> bigassign(zalloc(), a)
+}
- v = zalloc()
- v.dig = sldup(a.dig)
- v.sign = a.sign
- -> v
+const bigassign = {d, s
+ slfree(d.dig)
+ d.dig = sldup(s.dig)
+ d.sign = s.sign
+ -> d
}
+
/* for now, just dump out something for debugging... */
const bigfmt = {buf, val
const digitchars = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
@@ -173,23 +177,23 @@ const bigcmp = {a, b
else
/* the one with more digits has greater magnitude */
if a.dig.len > b.dig.len
- -> signedmagorder(a.sign)
+ -> signedorder(a.sign)
;;
/* otherwise, the one with the first larger digit is bigger */
for i = a.dig.len; i > 0; i--
if a.dig[i - 1] > b.dig[i - 1]
- -> signedmagorder(a.sign)
+ -> signedorder(a.sign)
elif b.dig[i - 1] > a.dig[i - 1]
- -> signedmagorder(a.sign)
+ -> signedorder(a.sign)
;;
;;
;;
-> `Equal
}
-const signedmagorder = {sign
+const signedorder = {sign
if sign < 0
- -> `Before
+ -> `Before
else
-> `After
;;
@@ -240,7 +244,15 @@ const uadd = {a, b
/* a -= b */
const bigsub = {a, b
- if a.sign != b.sign
+ /* 0 - x = -x */
+ if a.sign == 0
+ bigassign(a, b)
+ a.sign = -b.sign
+ -> a
+ /* x - 0 = x */
+ elif b.sign == 0
+ -> a
+ elif a.sign != b.sign
-> uadd(a, b)
else
match bigcmp(a, b)
@@ -281,8 +293,12 @@ const bigmul = {a, b
var carry, t
var w
- /* trim() will take care of the zero case */
- if a.sign != b.sign
+ if a.sign == 0 || b.sign == 0
+ a.sign = 0
+ slfree(a.dig)
+ a.dig = [][:]
+ -> a
+ elif a.sign != b.sign
a.sign = -1
else
a.sign = 1