Commit e2fe2f3f authored by Robert Griesemer's avatar Robert Griesemer

- better support for string conversions

- removed trailing tabs

R=r
OCL=18458
CL=18458
parent d289e634
...@@ -730,7 +730,8 @@ func MulAdd1(x *Natural, d, c Digit) *Natural { ...@@ -730,7 +730,8 @@ func MulAdd1(x *Natural, d, c Digit) *Natural {
// Determines base (octal, decimal, hexadecimal) if base == 0. // Determines base (octal, decimal, hexadecimal) if base == 0.
export func NatFromString(s string, base uint, slen *int) *Natural { // Returns the number and base.
export func NatFromString(s string, base uint, slen *int) (*Natural, uint) {
// determine base if necessary // determine base if necessary
i, n := 0, len(s); i, n := 0, len(s);
if base == 0 { if base == 0 {
...@@ -761,7 +762,7 @@ export func NatFromString(s string, base uint, slen *int) *Natural { ...@@ -761,7 +762,7 @@ export func NatFromString(s string, base uint, slen *int) *Natural {
*slen = i; *slen = i;
} }
return x; return x, base;
} }
...@@ -1104,7 +1105,8 @@ func (x *Integer) String(base uint) string { ...@@ -1104,7 +1105,8 @@ func (x *Integer) String(base uint) string {
// Determines base (octal, decimal, hexadecimal) if base == 0. // Determines base (octal, decimal, hexadecimal) if base == 0.
export func IntFromString(s string, base uint, slen *int) *Integer { // Returns the number and base.
export func IntFromString(s string, base uint, slen *int) (*Integer, uint) {
// get sign, if any // get sign, if any
sign := false; sign := false;
if len(s) > 0 && (s[0] == '-' || s[0] == '+') { if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
...@@ -1112,14 +1114,15 @@ export func IntFromString(s string, base uint, slen *int) *Integer { ...@@ -1112,14 +1114,15 @@ export func IntFromString(s string, base uint, slen *int) *Integer {
s = s[1 : len(s)]; s = s[1 : len(s)];
} }
z := MakeInt(sign, NatFromString(s, base, slen)); var mant *Natural;
mant, base = NatFromString(s, base, slen);
// correct slen if necessary // correct slen if necessary
if slen != nil && sign { if slen != nil && sign {
*slen++; *slen++;
} }
return z; return MakeInt(sign, mant), base;
} }
...@@ -1222,17 +1225,26 @@ func (x *Rational) String(base uint) string { ...@@ -1222,17 +1225,26 @@ func (x *Rational) String(base uint) string {
// Determines base (octal, decimal, hexadecimal) if base == 0. // Determines base (octal, decimal, hexadecimal) if base == 0.
export func RatFromString(s string, base uint, slen *int) *Rational { // Returns the number and base of the nominator.
export func RatFromString(s string, base uint, slen *int) (*Rational, uint) {
// read nominator // read nominator
var alen, blen int; var alen, blen int;
a := IntFromString(s, base, &alen); a, abase := IntFromString(s, base, &alen);
b := Nat(1); b := Nat(1);
// read denominator, if any // read denominator or fraction, if any
if alen < len(s) && s[alen] == '/' {
alen++;
if alen < len(s) { if alen < len(s) {
b = NatFromString(s[alen : len(s)], base, &blen); ch := s[alen];
if ch == '/' {
alen++;
b, base = NatFromString(s[alen : len(s)], base, &blen);
} else if ch == '.' {
alen++;
b, base = NatFromString(s[alen : len(s)], abase, &blen);
assert(base == abase);
f := Nat(base).Pow(uint(blen));
a = MakeInt(a.sign, a.mant.Mul(f).Add(b));
b = f;
} }
} }
...@@ -1241,5 +1253,5 @@ export func RatFromString(s string, base uint, slen *int) *Rational { ...@@ -1241,5 +1253,5 @@ export func RatFromString(s string, base uint, slen *int) *Rational {
*slen = alen + blen; *slen = alen + blen;
} }
return MakeRat(a, b); return MakeRat(a, b), abase;
} }
...@@ -16,21 +16,39 @@ const ( ...@@ -16,21 +16,39 @@ const (
) )
func NatFromString(s string, base uint, slen *int) *Big.Natural {
x, dummy := Big.NatFromString(s, base, slen);
return x;
}
func IntFromString(s string, base uint, slen *int) *Big.Integer {
x, dummy := Big.IntFromString(s, base, slen);
return x;
}
func RatFromString(s string, base uint, slen *int) *Big.Rational {
x, dummy := Big.RatFromString(s, base, slen);
return x;
}
var ( var (
nat_zero = Big.Nat(0); nat_zero = Big.Nat(0);
nat_one = Big.Nat(1); nat_one = Big.Nat(1);
nat_two = Big.Nat(2); nat_two = Big.Nat(2);
a = Big.NatFromString(sa, 10, nil); a = NatFromString(sa, 10, nil);
b = Big.NatFromString(sb, 10, nil); b = NatFromString(sb, 10, nil);
c = Big.NatFromString(sc, 10, nil); c = NatFromString(sc, 10, nil);
p = Big.NatFromString(sp, 10, nil); p = NatFromString(sp, 10, nil);
int_zero = Big.Int(0); int_zero = Big.Int(0);
int_one = Big.Int(1); int_one = Big.Int(1);
int_two = Big.Int(2); int_two = Big.Int(2);
ip = Big.IntFromString(sp, 10, nil); ip = IntFromString(sp, 10, nil);
rat_zero = Big.Rat(0, 1); rat_zero = Big.Rat(0, 1);
rat_half = Big.Rat(1, 2); rat_half = Big.Rat(1, 2);
...@@ -89,17 +107,17 @@ func NatConv() { ...@@ -89,17 +107,17 @@ func NatConv() {
test_msg = "NatConvB"; test_msg = "NatConvB";
var slen int; var slen int;
NAT_EQ(0, Big.NatFromString("0", 0, nil), nat_zero); NAT_EQ(0, NatFromString("0", 0, nil), nat_zero);
NAT_EQ(1, Big.NatFromString("123", 0, nil), Big.Nat(123)); NAT_EQ(1, NatFromString("123", 0, nil), Big.Nat(123));
NAT_EQ(2, Big.NatFromString("077", 0, nil), Big.Nat(7*8 + 7)); NAT_EQ(2, NatFromString("077", 0, nil), Big.Nat(7*8 + 7));
NAT_EQ(3, Big.NatFromString("0x1f", 0, nil), Big.Nat(1*16 + 15)); NAT_EQ(3, NatFromString("0x1f", 0, nil), Big.Nat(1*16 + 15));
NAT_EQ(4, Big.NatFromString("0x1fg", 0, &slen), Big.Nat(1*16 + 15)); NAT_EQ(4, NatFromString("0x1fg", 0, &slen), Big.Nat(1*16 + 15));
TEST(4, slen == 4); TEST(4, slen == 4);
test_msg = "NatConvC"; test_msg = "NatConvC";
t := c.Mul(c); t := c.Mul(c);
for base := uint(2); base <= 16; base++ { for base := uint(2); base <= 16; base++ {
NAT_EQ(base, Big.NatFromString(t.String(base), base, nil), t); NAT_EQ(base, NatFromString(t.String(base), base, nil), t);
} }
} }
...@@ -107,16 +125,16 @@ func NatConv() { ...@@ -107,16 +125,16 @@ func NatConv() {
func IntConv() { func IntConv() {
test_msg = "IntConv"; test_msg = "IntConv";
var slen int; var slen int;
INT_EQ(0, Big.IntFromString("0", 0, nil), int_zero); INT_EQ(0, IntFromString("0", 0, nil), int_zero);
INT_EQ(1, Big.IntFromString("-0", 0, nil), int_zero); INT_EQ(1, IntFromString("-0", 0, nil), int_zero);
INT_EQ(2, Big.IntFromString("123", 0, nil), Big.Int(123)); INT_EQ(2, IntFromString("123", 0, nil), Big.Int(123));
INT_EQ(3, Big.IntFromString("-123", 0, nil), Big.Int(-123)); INT_EQ(3, IntFromString("-123", 0, nil), Big.Int(-123));
INT_EQ(4, Big.IntFromString("077", 0, nil), Big.Int(7*8 + 7)); INT_EQ(4, IntFromString("077", 0, nil), Big.Int(7*8 + 7));
INT_EQ(5, Big.IntFromString("-077", 0, nil), Big.Int(-(7*8 + 7))); INT_EQ(5, IntFromString("-077", 0, nil), Big.Int(-(7*8 + 7)));
INT_EQ(6, Big.IntFromString("0x1f", 0, nil), Big.Int(1*16 + 15)); INT_EQ(6, IntFromString("0x1f", 0, nil), Big.Int(1*16 + 15));
INT_EQ(7, Big.IntFromString("-0x1f", 0, nil), Big.Int(-(1*16 + 15))); INT_EQ(7, IntFromString("-0x1f", 0, nil), Big.Int(-(1*16 + 15)));
INT_EQ(8, Big.IntFromString("0x1fg", 0, &slen), Big.Int(1*16 + 15)); INT_EQ(8, IntFromString("0x1fg", 0, &slen), Big.Int(1*16 + 15));
INT_EQ(9, Big.IntFromString("-0x1fg", 0, &slen), Big.Int(-(1*16 + 15))); INT_EQ(9, IntFromString("-0x1fg", 0, &slen), Big.Int(-(1*16 + 15)));
TEST(10, slen == 5); TEST(10, slen == 5);
} }
...@@ -124,12 +142,16 @@ func IntConv() { ...@@ -124,12 +142,16 @@ func IntConv() {
func RatConv() { func RatConv() {
test_msg = "RatConv"; test_msg = "RatConv";
var slen int; var slen int;
RAT_EQ(0, Big.RatFromString("0", 0, nil), rat_zero); RAT_EQ(0, RatFromString("0", 0, nil), rat_zero);
RAT_EQ(1, Big.RatFromString("0/", 0, nil), rat_zero); RAT_EQ(1, RatFromString("0/1", 0, nil), rat_zero);
RAT_EQ(2, Big.RatFromString("0/1", 0, nil), rat_zero); RAT_EQ(2, RatFromString("0/01", 0, nil), rat_zero);
RAT_EQ(3, Big.RatFromString("010/8", 0, nil), rat_one); RAT_EQ(3, RatFromString("0x14/10", 0, &slen), rat_two);
RAT_EQ(4, Big.RatFromString("20/0xa", 0, &slen), rat_two); TEST(4, slen == 7);
TEST(5, slen == 6); RAT_EQ(5, RatFromString("0.", 0, nil), rat_zero);
RAT_EQ(6, RatFromString("0.001f", 10, nil), Big.Rat(1, 1000));
RAT_EQ(7, RatFromString("10101.0101", 2, nil), Big.Rat(0x155, 1<<4));
RAT_EQ(8, RatFromString("-0003.145926", 10, &slen), Big.Rat(-3145926, 1000000));
TEST(9, slen == 12);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment