Commit 8d701f09 authored by Robert Griesemer's avatar Robert Griesemer

math/big: implement Int.Text, Int.Append

This makes the Int conversion routines match the respective strconv
and big.Float conversion routines.

Change-Id: I5cfcda1632ee52fe87c5bb75892bdda76cc3af15
Reviewed-on: https://go-review.googlesource.com/14994Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 707b619c
...@@ -12,14 +12,41 @@ import ( ...@@ -12,14 +12,41 @@ import (
"io" "io"
) )
func (x *Int) String() string { // TODO(gri) Should rename itoa to utoa (there's no sign). That
switch { // would permit the introduction of itoa which is like utoa but
case x == nil: // reserves a byte for a possible sign that's passed in. That
// would permit Int.Text to be implemented w/o the need for
// string copy if the number is negative.
// Text returns the string representation of x in the given base.
// Base must be between 2 and 36, inclusive. The result uses the
// lower-case letters 'a' to 'z' for digit values >= 10. No base
// prefix (such as "0x") is added to the string.
func (x *Int) Text(base int) string {
if x == nil {
return "<nil>" return "<nil>"
case x.neg:
return "-" + string(x.abs.itoa(10))
} }
return string(x.abs.itoa(10)) s := string(x.abs.itoa(base))
if x.neg {
s = "-" + s
}
return s
}
// Append appends the string representation of x, as generated by
// x.Text(base), to buf and returns the extended buffer.
func (x *Int) Append(buf []byte, base int) []byte {
if x == nil {
return append(buf, "<nil>"...)
}
if x.neg {
buf = append(buf, '-')
}
return append(buf, x.abs.itoa(base)...)
}
func (x *Int) String() string {
return x.Text(10)
} }
// write count copies of text to s // write count copies of text to s
......
...@@ -17,19 +17,19 @@ var stringTests = []struct { ...@@ -17,19 +17,19 @@ var stringTests = []struct {
val int64 val int64
ok bool ok bool
}{ }{
{in: "", ok: false}, {in: ""},
{in: "a", ok: false}, {in: "a"},
{in: "z", ok: false}, {in: "z"},
{in: "+", ok: false}, {in: "+"},
{in: "-", ok: false}, {in: "-"},
{in: "0b", ok: false}, {in: "0b"},
{in: "0x", ok: false}, {in: "0x"},
{in: "2", base: 2, ok: false}, {in: "2", base: 2},
{in: "0b2", base: 0, ok: false}, {in: "0b2", base: 0},
{in: "08", ok: false}, {in: "08"},
{in: "8", base: 8, ok: false}, {in: "8", base: 8},
{in: "0xg", base: 0, ok: false}, {in: "0xg", base: 0},
{in: "g", base: 16, ok: false}, {in: "g", base: 16},
{"0", "0", 0, 0, true}, {"0", "0", 0, 0, true},
{"0", "0", 10, 0, true}, {"0", "0", 10, 0, true},
{"0", "0", 16, 0, true}, {"0", "0", 16, 0, true},
...@@ -41,7 +41,7 @@ var stringTests = []struct { ...@@ -41,7 +41,7 @@ var stringTests = []struct {
{"-10", "-10", 16, -16, true}, {"-10", "-10", 16, -16, true},
{"+10", "10", 16, 16, true}, {"+10", "10", 16, 16, true},
{"0x10", "16", 0, 16, true}, {"0x10", "16", 0, 16, true},
{in: "0x10", base: 16, ok: false}, {in: "0x10", base: 16},
{"-0x10", "-16", 0, -16, true}, {"-0x10", "-16", 0, -16, true},
{"+0x10", "16", 0, 16, true}, {"+0x10", "16", 0, 16, true},
{"00", "0", 0, 0, true}, {"00", "0", 0, 0, true},
...@@ -58,6 +58,57 @@ var stringTests = []struct { ...@@ -58,6 +58,57 @@ var stringTests = []struct {
{"1001010111", "1001010111", 2, 0x257, true}, {"1001010111", "1001010111", 2, 0x257, true},
} }
func TestIntText(t *testing.T) {
z := new(Int)
for _, test := range stringTests {
if !test.ok {
continue
}
_, ok := z.SetString(test.in, test.base)
if !ok {
t.Errorf("%v: failed to parse", test)
continue
}
base := test.base
if base == 0 {
base = 10
}
if got := z.Text(base); got != test.out {
t.Errorf("%v: got %s; want %s", test, got, test.out)
}
}
}
func TestAppendText(t *testing.T) {
z := new(Int)
var buf []byte
for _, test := range stringTests {
if !test.ok {
continue
}
_, ok := z.SetString(test.in, test.base)
if !ok {
t.Errorf("%v: failed to parse", test)
continue
}
base := test.base
if base == 0 {
base = 10
}
i := len(buf)
buf = z.Append(buf, base)
if got := string(buf[i:]); got != test.out {
t.Errorf("%v: got %s; want %s", test, got, test.out)
}
}
}
func format(base int) string { func format(base int) string {
switch base { switch base {
case 2: case 2:
...@@ -79,15 +130,13 @@ func TestGetString(t *testing.T) { ...@@ -79,15 +130,13 @@ func TestGetString(t *testing.T) {
z.SetInt64(test.val) z.SetInt64(test.val)
if test.base == 10 { if test.base == 10 {
s := z.String() if got := z.String(); got != test.out {
if s != test.out { t.Errorf("#%da got %s; want %s", i, got, test.out)
t.Errorf("#%da got %s; want %s", i, s, test.out)
} }
} }
s := fmt.Sprintf(format(test.base), z) if got := fmt.Sprintf(format(test.base), z); got != test.out {
if s != test.out { t.Errorf("#%db got %s; want %s", i, got, test.out)
t.Errorf("#%db got %s; want %s", i, s, test.out)
} }
} }
} }
......
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