Commit 66c6b13b authored by Robert Griesemer's avatar Robert Griesemer

- implemented String() and Format functionality in Bignum

- added a test

R=r
OCL=18687
CL=18687
parent 3a2c0a96
...@@ -11,6 +11,7 @@ package Bignum ...@@ -11,6 +11,7 @@ package Bignum
// - Integer signed integer numbers // - Integer signed integer numbers
// - Rational rational numbers // - Rational rational numbers
import Fmt "fmt"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Internal representation // Internal representation
...@@ -675,7 +676,7 @@ func DivMod1(x *Natural, d Digit) (*Natural, Digit) { ...@@ -675,7 +676,7 @@ func DivMod1(x *Natural, d Digit) (*Natural, Digit) {
} }
func (x *Natural) String(base uint) string { func (x *Natural) ToString(base uint) string {
if len(x) == 0 { if len(x) == 0 {
return "0"; return "0";
} }
...@@ -702,6 +703,27 @@ func (x *Natural) String(base uint) string { ...@@ -702,6 +703,27 @@ func (x *Natural) String(base uint) string {
} }
func (x *Natural) String() string {
return x.ToString(10);
}
func FmtBase(c int) uint {
switch c {
case 'b': return 2;
case 'o': return 8;
case 'x': return 16;
}
return 10;
}
func (x *Natural) Format(h Fmt.Formatter, c int) {
t := x.ToString(FmtBase(c)); // BUG in 6g
Fmt.fprintf(h, "%s", t);
}
func HexValue(ch byte) uint { func HexValue(ch byte) uint {
d := uint(1 << LogH); d := uint(1 << LogH);
switch { switch {
...@@ -1092,7 +1114,7 @@ func (x *Integer) Cmp(y *Integer) int { ...@@ -1092,7 +1114,7 @@ func (x *Integer) Cmp(y *Integer) int {
} }
func (x *Integer) String(base uint) string { func (x *Integer) ToString(base uint) string {
if x.mant.IsZero() { if x.mant.IsZero() {
return "0"; return "0";
} }
...@@ -1100,7 +1122,18 @@ func (x *Integer) String(base uint) string { ...@@ -1100,7 +1122,18 @@ func (x *Integer) String(base uint) string {
if x.sign { if x.sign {
s = "-"; s = "-";
} }
return s + x.mant.String(base); return s + x.mant.ToString(base);
}
func (x *Integer) String() string {
return x.ToString(10);
}
func (x *Integer) Format(h Fmt.Formatter, c int) {
t := x.ToString(FmtBase(c)); // BUG in 6g
Fmt.fprintf(h, "%s", t);
} }
...@@ -1215,15 +1248,26 @@ func (x *Rational) Cmp(y *Rational) int { ...@@ -1215,15 +1248,26 @@ func (x *Rational) Cmp(y *Rational) int {
} }
func (x *Rational) String(base uint) string { func (x *Rational) ToString(base uint) string {
s := x.a.String(base); s := x.a.ToString(base);
if !x.IsInt() { if !x.IsInt() {
s += "/" + x.b.String(base); s += "/" + x.b.ToString(base);
} }
return s; return s;
} }
func (x *Rational) String() string {
return x.ToString(10);
}
func (x *Rational) Format(h Fmt.Formatter, c int) {
t := x.ToString(FmtBase(c)); // BUG in 6g
Fmt.fprintf(h, "%s", t);
}
// Determines base (octal, decimal, hexadecimal) if base == 0. // Determines base (octal, decimal, hexadecimal) if base == 0.
// Returns the number and base of the nominator. // Returns the number and base of the nominator.
export func RatFromString(s string, base uint, slen *int) (*Rational, uint) { export func RatFromString(s string, base uint, slen *int) (*Rational, uint) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package main package main
import Big "bignum" import Big "bignum"
import Fmt "fmt"
const ( const (
sa = "991"; sa = "991";
...@@ -71,8 +72,8 @@ func TEST(n uint, b bool) { ...@@ -71,8 +72,8 @@ func TEST(n uint, b bool) {
func NAT_EQ(n uint, x, y *Big.Natural) { func NAT_EQ(n uint, x, y *Big.Natural) {
if x.Cmp(y) != 0 { if x.Cmp(y) != 0 {
println("TEST failed:", test_msg, "(", n, ")"); println("TEST failed:", test_msg, "(", n, ")");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
} }
...@@ -81,8 +82,8 @@ func NAT_EQ(n uint, x, y *Big.Natural) { ...@@ -81,8 +82,8 @@ func NAT_EQ(n uint, x, y *Big.Natural) {
func INT_EQ(n uint, x, y *Big.Integer) { func INT_EQ(n uint, x, y *Big.Integer) {
if x.Cmp(y) != 0 { if x.Cmp(y) != 0 {
println("TEST failed:", test_msg, "(", n, ")"); println("TEST failed:", test_msg, "(", n, ")");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
} }
...@@ -91,8 +92,8 @@ func INT_EQ(n uint, x, y *Big.Integer) { ...@@ -91,8 +92,8 @@ func INT_EQ(n uint, x, y *Big.Integer) {
func RAT_EQ(n uint, x, y *Big.Rational) { func RAT_EQ(n uint, x, y *Big.Rational) {
if x.Cmp(y) != 0 { if x.Cmp(y) != 0 {
println("TEST failed:", test_msg, "(", n, ")"); println("TEST failed:", test_msg, "(", n, ")");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
} }
...@@ -103,9 +104,9 @@ func NatConv() { ...@@ -103,9 +104,9 @@ func NatConv() {
NAT_EQ(0, a, Big.Nat(991)); NAT_EQ(0, a, Big.Nat(991));
NAT_EQ(1, b, Big.Fact(20)); NAT_EQ(1, b, Big.Fact(20));
NAT_EQ(2, c, Big.Fact(100)); NAT_EQ(2, c, Big.Fact(100));
TEST(3, a.String(10) == sa); TEST(3, a.String() == sa);
TEST(4, b.String(10) == sb); TEST(4, b.String() == sb);
TEST(5, c.String(10) == sc); TEST(5, c.String() == sc);
test_msg = "NatConvB"; test_msg = "NatConvB";
var slen int; var slen int;
...@@ -119,8 +120,13 @@ func NatConv() { ...@@ -119,8 +120,13 @@ func NatConv() {
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, NatFromString(t.String(base), base, nil), t); NAT_EQ(base, NatFromString(t.ToString(base), base, nil), t);
} }
test_msg = "NatConvD";
x := Big.Nat(100);
y, b := Big.NatFromString(Fmt.sprintf("%b", x), 2, nil);
NAT_EQ(0, y, x);
} }
...@@ -162,8 +168,8 @@ func Add(x, y *Big.Natural) *Big.Natural { ...@@ -162,8 +168,8 @@ func Add(x, y *Big.Natural) *Big.Natural {
z2 := y.Add(x); z2 := y.Add(x);
if z1.Cmp(z2) != 0 { if z1.Cmp(z2) != 0 {
println("addition not symmetric"); println("addition not symmetric");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
return z1; return z1;
...@@ -197,20 +203,20 @@ func Mul(x, y *Big.Natural) *Big.Natural { ...@@ -197,20 +203,20 @@ func Mul(x, y *Big.Natural) *Big.Natural {
z2 := y.Mul(x); z2 := y.Mul(x);
if z1.Cmp(z2) != 0 { if z1.Cmp(z2) != 0 {
println("multiplication not symmetric"); println("multiplication not symmetric");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
if !x.IsZero() && z1.Div(x).Cmp(y) != 0 { if !x.IsZero() && z1.Div(x).Cmp(y) != 0 {
println("multiplication/division not inverse (A)"); println("multiplication/division not inverse (A)");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
if !y.IsZero() && z1.Div(y).Cmp(x) != 0 { if !y.IsZero() && z1.Div(y).Cmp(x) != 0 {
println("multiplication/division not inverse (B)"); println("multiplication/division not inverse (B)");
println("x =", x.String(10)); println("x =", x.String());
println("y =", y.String(10)); println("y =", y.String());
panic(); panic();
} }
return z1; return z1;
......
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