ref: 8f2b7470799a4851a5f73e8566b18823c7fe72df
parent: 4a59ae120acc8cbb8ee2bccbd0bcbd171f8db7b5
author: Ori Bernstein <[email protected]>
date: Sat Sep 13 23:21:03 EDT 2014
Fix bigint parsing for hex. We weren't trimming the '0x' hex prefix,and that confused our code when it got the 'x' and tried to treat it as a digit.
--- a/libstd/bigint.myr
+++ b/libstd/bigint.myr
@@ -166,7 +166,7 @@
}
const bigparse = {str
- var c, val : uint32, base
+ var c, val : int, base
var v, b
var a
@@ -179,9 +179,12 @@
else
base = 10
;;
+ if base != 10
+ str = str[2:]
+ ;;
a = mkbigint(0)
- b = mkbigint(base castto(int32))
+ b = mkbigint(base)
/*
efficiency hack: to save allocations,
just mutate v[0]. The value will always
@@ -194,11 +197,13 @@
continue
;;
val = charval(c, base)
- if val < 0
+ if val < 0 || val > base
bigfree(a)
+ bigfree(b)
+ bigfree(v)
-> `None
;;
- v.dig[0] = val
+ v.dig[0] = val castto(uint32)
if val == 0
v.sign = 0
else
--- a/test/bigint.myr
+++ /dev/null
@@ -1,96 +1,0 @@
-use std
-
-const main = {
- var a, b, c, d, e
- var buf : byte[4096], n
-
- a = std.mkbigint(1234)
- b = std.mkbigint(0x7fffffff)
- c = std.mkbigint(7919)
- d = std.mkbigint(113051)
- e = std.mkbigint(11)
-
- std.bigmul(a, b)
- std.bigmul(a, b)
- std.bigadd(a, c)
- std.bigsub(a, d)
- std.bigdiv(a, e)
-
- std.bigfree(b)
- std.bigfree(c)
- std.bigfree(d)
- std.bigfree(e)
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s\n", buf[:n])
-
- /* smoke test */
- match std.bigparse("1234_5678_1234_6789_6666_7777_8888")
- | `std.Some val: a = val
- | `std.None: std.die("Failed to parse a\n")
- ;;
- match std.bigparse("1234_5678_1234_6789_6666_7777")
- | `std.Some val: b = val
- | `std.None: std.die("Failed to parse b\n")
- ;;
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s / ", buf[:n])
- n = std.bigbfmt(buf[:], b, 0)
- std.put("%s == ", buf[:n])
-
- std.bigdiv(a, b)
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s\n", buf[:n])
-
- /* test big shifts */
- a = std.mkbigint(1)
- var shift = 4095
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s << %i == 0x", buf[:n], shift)
- std.bigshli(a, shift)
- n = std.bigbfmt(buf[:], a, 10)
- std.put("%s\n", buf[:n])
- std.put("top bits: %xi\n", a.dig[a.dig.len - 1])
-
- /* no shifting */
- match std.bigparse("0xffff_1234_1234_1234_1234")
- | `std.Some val: a = val
- | `std.None: std.die("Failed to parse a\n")
- ;;
- match std.bigparse("0xf010_1234_2314")
- | `std.Some val: b = val
- | `std.None: std.die("Failed to parse b\n")
- ;;
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s / ", buf[:n])
- n = std.bigbfmt(buf[:], b, 0)
- std.put("%s == ", buf[:n])
-
- std.bigdiv(a, b)
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s\n", buf[:n])
-
- /* no shifting */
- match std.bigparse("0xffff_1234_1234_1234_1234")
- | `std.Some val: a = val
- | `std.None: std.die("Failed to parse a\n")
- ;;
- match std.bigparse("0x0ff_1234_2314")
- | `std.Some val: b = val
- | `std.None: std.die("Failed to parse b\n")
- ;;
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s / ", buf[:n])
- n = std.bigbfmt(buf[:], b, 0)
- std.put("%s == ", buf[:n])
-
- std.bigdiv(a, b)
-
- n = std.bigbfmt(buf[:], a, 0)
- std.put("%s\n", buf[:n])
-}
--- a/test/data/bigint-expected
+++ /dev/null
@@ -1,4 +1,0 @@
-517347321949036993306
-1234567812346789666677778888 / 123456781234678966667777 == 10000
-5192296858534810493479828944327220 / 1208925819597106013545236 == 4294967296
-5192296858534810493479828944327220 / 75557863709417659441940 == 68719476751
--- /dev/null
+++ b/test/data/stdbigint-expected
@@ -1,0 +1,4 @@
+517347321949036993306
+1234567812346789666677778888 / 123456781234678966667777 == 10000
+5192296858534810493479828944327220 / 1208925819597106013545236 == 4294967296
+5192296858534810493479828944327220 / 75557863709417659441940 == 68719476751
--- /dev/null
+++ b/test/stdbigint.myr
@@ -1,0 +1,88 @@
+use std
+
+const main = {
+ var a, b, c, d, e
+ var buf : byte[4096], n
+
+ a = std.mkbigint(1234)
+ b = std.mkbigint(0x7fffffff)
+ c = std.mkbigint(7919)
+ d = std.mkbigint(113051)
+ e = std.mkbigint(11)
+
+ std.bigmul(a, b)
+ std.bigmul(a, b)
+ std.bigadd(a, c)
+ std.bigsub(a, d)
+ std.bigdiv(a, e)
+
+ std.bigfree(b)
+ std.bigfree(c)
+ std.bigfree(d)
+ std.bigfree(e)
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s\n", buf[:n])
+
+ /* smoke test */
+ match std.bigparse("1234_5678_1234_6789_6666_7777_8888")
+ | `std.Some val: a = val
+ | `std.None: std.die("Failed to parse a\n")
+ ;;
+ match std.bigparse("1234_5678_1234_6789_6666_7777")
+ | `std.Some val: b = val
+ | `std.None: std.die("Failed to parse b\n")
+ ;;
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s / ", buf[:n])
+ n = std.bigbfmt(buf[:], b, 0)
+ std.put("%s == ", buf[:n])
+
+ std.bigdiv(a, b)
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s\n", buf[:n])
+
+ match std.bigparse("0xffff_1234_1234_1234_1234")
+ | `std.Some val: a = val
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("a = %s \n", buf[:n])
+ | `std.None: std.die("Failed to parse a\n")
+ ;;
+ match std.bigparse("0xf010_1234_2314")
+ | `std.Some val: b = val
+ | `std.None: std.die("Failed to parse b\n")
+ ;;
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s / ", buf[:n])
+ n = std.bigbfmt(buf[:], b, 0)
+ std.put("%s == ", buf[:n])
+
+ std.bigdiv(a, b)
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s\n", buf[:n])
+
+ match std.bigparse("5192296858534810493479828944327220")
+ | `std.Some val: a = val
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("a = %s \n", buf[:n])
+ | `std.None: std.die("Failed to parse a\n")
+ ;;
+ match std.bigparse("75557863709417659441940")
+ | `std.Some val: b = val
+ | `std.None: std.die("Failed to parse b\n")
+ ;;
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s / ", buf[:n])
+ n = std.bigbfmt(buf[:], b, 0)
+ std.put("%s == ", buf[:n])
+
+ std.bigdiv(a, b)
+
+ n = std.bigbfmt(buf[:], a, 0)
+ std.put("%s\n", buf[:n])
+}
--- a/test/tests
+++ b/test/tests
@@ -133,7 +133,7 @@
B stdslcp C
B stdfmtpad C
B stdpathnorm C
-B bigint C
+B stdbigint C
B exporttrait
# B local-labels E 10 ## BUGGERED
F declmismatch