]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: implement Int.Text, Int.Append
authorRobert Griesemer <gri@golang.org>
Thu, 24 Sep 2015 23:36:08 +0000 (16:36 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 25 Sep 2015 22:24:49 +0000 (22:24 +0000)
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 <adonovan@google.com>
src/math/big/intconv.go
src/math/big/intconv_test.go

index 4693b171598a787d56d72f91678f8814a753e10d..524f775a3936112ccff056bb616bce45bcb0b310 100644 (file)
@@ -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
index 2deb84b48f68a4fd667faca454bcbac2dcc95504..514208145fdf119ba98191c9102ca7f9fec656d5 100644 (file)
@@ -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},
@@ -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},
@@ -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:
@@ -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)
                }
        }
 }