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 {
// 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
i, n := 0, len(s);
if base == 0 {
......@@ -761,7 +762,7 @@ export func NatFromString(s string, base uint, slen *int) *Natural {
*slen = i;
}
return x;
return x, base;
}
......@@ -1104,7 +1105,8 @@ func (x *Integer) String(base uint) string {
// 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
sign := false;
if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
......@@ -1112,14 +1114,15 @@ export func IntFromString(s string, base uint, slen *int) *Integer {
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
if slen != nil && sign {
*slen++;
}
return z;
return MakeInt(sign, mant), base;
}
......@@ -1222,17 +1225,26 @@ func (x *Rational) String(base uint) string {
// 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
var alen, blen int;
a := IntFromString(s, base, &alen);
a, abase := IntFromString(s, base, &alen);
b := Nat(1);
// read denominator, if any
if alen < len(s) && s[alen] == '/' {
alen++;
// read denominator or fraction, if any
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 {
*slen = alen + blen;
}
return MakeRat(a, b);
return MakeRat(a, b), abase;
}
......@@ -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 (
nat_zero = Big.Nat(0);
nat_one = Big.Nat(1);
nat_two = Big.Nat(2);
a = Big.NatFromString(sa, 10, nil);
b = Big.NatFromString(sb, 10, nil);
c = Big.NatFromString(sc, 10, nil);
p = Big.NatFromString(sp, 10, nil);
a = NatFromString(sa, 10, nil);
b = NatFromString(sb, 10, nil);
c = NatFromString(sc, 10, nil);
p = NatFromString(sp, 10, nil);
int_zero = Big.Int(0);
int_one = Big.Int(1);
int_two = Big.Int(2);
ip = Big.IntFromString(sp, 10, nil);
ip = IntFromString(sp, 10, nil);
rat_zero = Big.Rat(0, 1);
rat_half = Big.Rat(1, 2);
......@@ -89,17 +107,17 @@ func NatConv() {
test_msg = "NatConvB";
var slen int;
NAT_EQ(0, Big.NatFromString("0", 0, nil), nat_zero);
NAT_EQ(1, Big.NatFromString("123", 0, nil), Big.Nat(123));
NAT_EQ(2, Big.NatFromString("077", 0, nil), Big.Nat(7*8 + 7));
NAT_EQ(3, Big.NatFromString("0x1f", 0, nil), Big.Nat(1*16 + 15));
NAT_EQ(4, Big.NatFromString("0x1fg", 0, &slen), Big.Nat(1*16 + 15));
NAT_EQ(0, NatFromString("0", 0, nil), nat_zero);
NAT_EQ(1, NatFromString("123", 0, nil), Big.Nat(123));
NAT_EQ(2, NatFromString("077", 0, nil), Big.Nat(7*8 + 7));
NAT_EQ(3, NatFromString("0x1f", 0, nil), Big.Nat(1*16 + 15));
NAT_EQ(4, NatFromString("0x1fg", 0, &slen), Big.Nat(1*16 + 15));
TEST(4, slen == 4);
test_msg = "NatConvC";
t := c.Mul(c);
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() {
func IntConv() {
test_msg = "IntConv";
var slen int;
INT_EQ(0, Big.IntFromString("0", 0, nil), int_zero);
INT_EQ(1, Big.IntFromString("-0", 0, nil), int_zero);
INT_EQ(2, Big.IntFromString("123", 0, nil), Big.Int(123));
INT_EQ(3, Big.IntFromString("-123", 0, nil), Big.Int(-123));
INT_EQ(4, Big.IntFromString("077", 0, nil), Big.Int(7*8 + 7));
INT_EQ(5, Big.IntFromString("-077", 0, nil), Big.Int(-(7*8 + 7)));
INT_EQ(6, Big.IntFromString("0x1f", 0, nil), Big.Int(1*16 + 15));
INT_EQ(7, Big.IntFromString("-0x1f", 0, nil), Big.Int(-(1*16 + 15)));
INT_EQ(8, Big.IntFromString("0x1fg", 0, &slen), Big.Int(1*16 + 15));
INT_EQ(9, Big.IntFromString("-0x1fg", 0, &slen), Big.Int(-(1*16 + 15)));
INT_EQ(0, IntFromString("0", 0, nil), int_zero);
INT_EQ(1, IntFromString("-0", 0, nil), int_zero);
INT_EQ(2, IntFromString("123", 0, nil), Big.Int(123));
INT_EQ(3, IntFromString("-123", 0, nil), Big.Int(-123));
INT_EQ(4, IntFromString("077", 0, nil), Big.Int(7*8 + 7));
INT_EQ(5, IntFromString("-077", 0, nil), Big.Int(-(7*8 + 7)));
INT_EQ(6, IntFromString("0x1f", 0, nil), Big.Int(1*16 + 15));
INT_EQ(7, IntFromString("-0x1f", 0, nil), Big.Int(-(1*16 + 15)));
INT_EQ(8, 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);
}
......@@ -124,12 +142,16 @@ func IntConv() {
func RatConv() {
test_msg = "RatConv";
var slen int;
RAT_EQ(0, Big.RatFromString("0", 0, nil), rat_zero);
RAT_EQ(1, Big.RatFromString("0/", 0, nil), rat_zero);
RAT_EQ(2, Big.RatFromString("0/1", 0, nil), rat_zero);
RAT_EQ(3, Big.RatFromString("010/8", 0, nil), rat_one);
RAT_EQ(4, Big.RatFromString("20/0xa", 0, &slen), rat_two);
TEST(5, slen == 6);
RAT_EQ(0, RatFromString("0", 0, nil), rat_zero);
RAT_EQ(1, RatFromString("0/1", 0, nil), rat_zero);
RAT_EQ(2, RatFromString("0/01", 0, nil), rat_zero);
RAT_EQ(3, RatFromString("0x14/10", 0, &slen), rat_two);
TEST(4, slen == 7);
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