"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
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},
{"-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},
{"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:
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)
}
}
}