Skip to content

Commit

Permalink
math/big: implement Int.Text, Int.Append
Browse files Browse the repository at this point in the history
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/14994
Reviewed-by: Alan Donovan <[email protected]>
  • Loading branch information
griesemer committed Sep 25, 2015
1 parent 707b619 commit 8d701f0
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 26 deletions.
39 changes: 33 additions & 6 deletions src/math/big/intconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,41 @@ import (
"io"
)

func (x *Int) String() string {
switch {
case x == nil:
// TODO(gri) Should rename itoa to utoa (there's no sign). That
// would permit the introduction of itoa which is like utoa but
// 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>"
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
Expand Down
89 changes: 69 additions & 20 deletions src/math/big/intconv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ var stringTests = []struct {
val int64
ok bool
}{
{in: "", ok: false},
{in: "a", ok: false},
{in: "z", ok: false},
{in: "+", ok: false},
{in: "-", ok: false},
{in: "0b", ok: false},
{in: "0x", ok: false},
{in: "2", base: 2, ok: false},
{in: "0b2", base: 0, ok: false},
{in: "08", ok: false},
{in: "8", base: 8, ok: false},
{in: "0xg", base: 0, ok: false},
{in: "g", base: 16, ok: false},
{in: ""},
{in: "a"},
{in: "z"},
{in: "+"},
{in: "-"},
{in: "0b"},
{in: "0x"},
{in: "2", base: 2},
{in: "0b2", base: 0},
{in: "08"},
{in: "8", base: 8},
{in: "0xg", base: 0},
{in: "g", base: 16},
{"0", "0", 0, 0, true},
{"0", "0", 10, 0, true},
{"0", "0", 16, 0, true},
Expand All @@ -41,7 +41,7 @@ var stringTests = []struct {
{"-10", "-10", 16, -16, true},
{"+10", "10", 16, 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},
{"00", "0", 0, 0, true},
Expand All @@ -58,6 +58,57 @@ var stringTests = []struct {
{"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 {
switch base {
case 2:
Expand All @@ -79,15 +130,13 @@ func TestGetString(t *testing.T) {
z.SetInt64(test.val)

if test.base == 10 {
s := z.String()
if s != test.out {
t.Errorf("#%da got %s; want %s", i, s, test.out)
if got := z.String(); got != test.out {
t.Errorf("#%da got %s; want %s", i, got, test.out)
}
}

s := fmt.Sprintf(format(test.base), z)
if s != test.out {
t.Errorf("#%db got %s; want %s", i, s, test.out)
if got := fmt.Sprintf(format(test.base), z); got != test.out {
t.Errorf("#%db got %s; want %s", i, got, test.out)
}
}
}
Expand Down

0 comments on commit 8d701f0

Please sign in to comment.