github.com/s1s1ty/go@v0.0.0-20180207192209-104445e3140f/src/math/big/intconv_test.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package big
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"testing"
    11  )
    12  
    13  var stringTests = []struct {
    14  	in   string
    15  	out  string
    16  	base int
    17  	val  int64
    18  	ok   bool
    19  }{
    20  	{in: ""},
    21  	{in: "a"},
    22  	{in: "z"},
    23  	{in: "+"},
    24  	{in: "-"},
    25  	{in: "0b"},
    26  	{in: "0x"},
    27  	{in: "2", base: 2},
    28  	{in: "0b2", base: 0},
    29  	{in: "08"},
    30  	{in: "8", base: 8},
    31  	{in: "0xg", base: 0},
    32  	{in: "g", base: 16},
    33  	{"0", "0", 0, 0, true},
    34  	{"0", "0", 10, 0, true},
    35  	{"0", "0", 16, 0, true},
    36  	{"+0", "0", 0, 0, true},
    37  	{"-0", "0", 0, 0, true},
    38  	{"10", "10", 0, 10, true},
    39  	{"10", "10", 10, 10, true},
    40  	{"10", "10", 16, 16, true},
    41  	{"-10", "-10", 16, -16, true},
    42  	{"+10", "10", 16, 16, true},
    43  	{"0x10", "16", 0, 16, true},
    44  	{in: "0x10", base: 16},
    45  	{"-0x10", "-16", 0, -16, true},
    46  	{"+0x10", "16", 0, 16, true},
    47  	{"00", "0", 0, 0, true},
    48  	{"0", "0", 8, 0, true},
    49  	{"07", "7", 0, 7, true},
    50  	{"7", "7", 8, 7, true},
    51  	{"023", "19", 0, 19, true},
    52  	{"23", "23", 8, 19, true},
    53  	{"cafebabe", "cafebabe", 16, 0xcafebabe, true},
    54  	{"0b0", "0", 0, 0, true},
    55  	{"-111", "-111", 2, -7, true},
    56  	{"-0b111", "-7", 0, -7, true},
    57  	{"0b1001010111", "599", 0, 0x257, true},
    58  	{"1001010111", "1001010111", 2, 0x257, true},
    59  	{"A", "a", 36, 10, true},
    60  	{"A", "A", 37, 36, true},
    61  	{"ABCXYZ", "abcxyz", 36, 623741435, true},
    62  	{"ABCXYZ", "ABCXYZ", 62, 33536793425, true},
    63  }
    64  
    65  func TestIntText(t *testing.T) {
    66  	z := new(Int)
    67  	for _, test := range stringTests {
    68  		if !test.ok {
    69  			continue
    70  		}
    71  
    72  		_, ok := z.SetString(test.in, test.base)
    73  		if !ok {
    74  			t.Errorf("%v: failed to parse", test)
    75  			continue
    76  		}
    77  
    78  		base := test.base
    79  		if base == 0 {
    80  			base = 10
    81  		}
    82  
    83  		if got := z.Text(base); got != test.out {
    84  			t.Errorf("%v: got %s; want %s", test, got, test.out)
    85  		}
    86  	}
    87  }
    88  
    89  func TestAppendText(t *testing.T) {
    90  	z := new(Int)
    91  	var buf []byte
    92  	for _, test := range stringTests {
    93  		if !test.ok {
    94  			continue
    95  		}
    96  
    97  		_, ok := z.SetString(test.in, test.base)
    98  		if !ok {
    99  			t.Errorf("%v: failed to parse", test)
   100  			continue
   101  		}
   102  
   103  		base := test.base
   104  		if base == 0 {
   105  			base = 10
   106  		}
   107  
   108  		i := len(buf)
   109  		buf = z.Append(buf, base)
   110  		if got := string(buf[i:]); got != test.out {
   111  			t.Errorf("%v: got %s; want %s", test, got, test.out)
   112  		}
   113  	}
   114  }
   115  
   116  func format(base int) string {
   117  	switch base {
   118  	case 2:
   119  		return "%b"
   120  	case 8:
   121  		return "%o"
   122  	case 16:
   123  		return "%x"
   124  	}
   125  	return "%d"
   126  }
   127  
   128  func TestGetString(t *testing.T) {
   129  	z := new(Int)
   130  	for i, test := range stringTests {
   131  		if !test.ok {
   132  			continue
   133  		}
   134  		z.SetInt64(test.val)
   135  
   136  		if test.base == 10 {
   137  			if got := z.String(); got != test.out {
   138  				t.Errorf("#%da got %s; want %s", i, got, test.out)
   139  			}
   140  		}
   141  
   142  		f := format(test.base)
   143  		got := fmt.Sprintf(f, z)
   144  		if f == "%d" {
   145  			if got != fmt.Sprintf("%d", test.val) {
   146  				t.Errorf("#%db got %s; want %d", i, got, test.val)
   147  			}
   148  		} else {
   149  			if got != test.out {
   150  				t.Errorf("#%dc got %s; want %s", i, got, test.out)
   151  			}
   152  		}
   153  	}
   154  }
   155  
   156  func TestSetString(t *testing.T) {
   157  	tmp := new(Int)
   158  	for i, test := range stringTests {
   159  		// initialize to a non-zero value so that issues with parsing
   160  		// 0 are detected
   161  		tmp.SetInt64(1234567890)
   162  		n1, ok1 := new(Int).SetString(test.in, test.base)
   163  		n2, ok2 := tmp.SetString(test.in, test.base)
   164  		expected := NewInt(test.val)
   165  		if ok1 != test.ok || ok2 != test.ok {
   166  			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
   167  			continue
   168  		}
   169  		if !ok1 {
   170  			if n1 != nil {
   171  				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
   172  			}
   173  			continue
   174  		}
   175  		if !ok2 {
   176  			if n2 != nil {
   177  				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
   178  			}
   179  			continue
   180  		}
   181  
   182  		if ok1 && !isNormalized(n1) {
   183  			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
   184  		}
   185  		if ok2 && !isNormalized(n2) {
   186  			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
   187  		}
   188  
   189  		if n1.Cmp(expected) != 0 {
   190  			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
   191  		}
   192  		if n2.Cmp(expected) != 0 {
   193  			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
   194  		}
   195  	}
   196  }
   197  
   198  var formatTests = []struct {
   199  	input  string
   200  	format string
   201  	output string
   202  }{
   203  	{"<nil>", "%x", "<nil>"},
   204  	{"<nil>", "%#x", "<nil>"},
   205  	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
   206  
   207  	{"10", "%b", "1010"},
   208  	{"10", "%o", "12"},
   209  	{"10", "%d", "10"},
   210  	{"10", "%v", "10"},
   211  	{"10", "%x", "a"},
   212  	{"10", "%X", "A"},
   213  	{"-10", "%X", "-A"},
   214  	{"10", "%y", "%!y(big.Int=10)"},
   215  	{"-10", "%y", "%!y(big.Int=-10)"},
   216  
   217  	{"10", "%#b", "1010"},
   218  	{"10", "%#o", "012"},
   219  	{"10", "%#d", "10"},
   220  	{"10", "%#v", "10"},
   221  	{"10", "%#x", "0xa"},
   222  	{"10", "%#X", "0XA"},
   223  	{"-10", "%#X", "-0XA"},
   224  	{"10", "%#y", "%!y(big.Int=10)"},
   225  	{"-10", "%#y", "%!y(big.Int=-10)"},
   226  
   227  	{"1234", "%d", "1234"},
   228  	{"1234", "%3d", "1234"},
   229  	{"1234", "%4d", "1234"},
   230  	{"-1234", "%d", "-1234"},
   231  	{"1234", "% 5d", " 1234"},
   232  	{"1234", "%+5d", "+1234"},
   233  	{"1234", "%-5d", "1234 "},
   234  	{"1234", "%x", "4d2"},
   235  	{"1234", "%X", "4D2"},
   236  	{"-1234", "%3x", "-4d2"},
   237  	{"-1234", "%4x", "-4d2"},
   238  	{"-1234", "%5x", " -4d2"},
   239  	{"-1234", "%-5x", "-4d2 "},
   240  	{"1234", "%03d", "1234"},
   241  	{"1234", "%04d", "1234"},
   242  	{"1234", "%05d", "01234"},
   243  	{"1234", "%06d", "001234"},
   244  	{"-1234", "%06d", "-01234"},
   245  	{"1234", "%+06d", "+01234"},
   246  	{"1234", "% 06d", " 01234"},
   247  	{"1234", "%-6d", "1234  "},
   248  	{"1234", "%-06d", "1234  "},
   249  	{"-1234", "%-06d", "-1234 "},
   250  
   251  	{"1234", "%.3d", "1234"},
   252  	{"1234", "%.4d", "1234"},
   253  	{"1234", "%.5d", "01234"},
   254  	{"1234", "%.6d", "001234"},
   255  	{"-1234", "%.3d", "-1234"},
   256  	{"-1234", "%.4d", "-1234"},
   257  	{"-1234", "%.5d", "-01234"},
   258  	{"-1234", "%.6d", "-001234"},
   259  
   260  	{"1234", "%8.3d", "    1234"},
   261  	{"1234", "%8.4d", "    1234"},
   262  	{"1234", "%8.5d", "   01234"},
   263  	{"1234", "%8.6d", "  001234"},
   264  	{"-1234", "%8.3d", "   -1234"},
   265  	{"-1234", "%8.4d", "   -1234"},
   266  	{"-1234", "%8.5d", "  -01234"},
   267  	{"-1234", "%8.6d", " -001234"},
   268  
   269  	{"1234", "%+8.3d", "   +1234"},
   270  	{"1234", "%+8.4d", "   +1234"},
   271  	{"1234", "%+8.5d", "  +01234"},
   272  	{"1234", "%+8.6d", " +001234"},
   273  	{"-1234", "%+8.3d", "   -1234"},
   274  	{"-1234", "%+8.4d", "   -1234"},
   275  	{"-1234", "%+8.5d", "  -01234"},
   276  	{"-1234", "%+8.6d", " -001234"},
   277  
   278  	{"1234", "% 8.3d", "    1234"},
   279  	{"1234", "% 8.4d", "    1234"},
   280  	{"1234", "% 8.5d", "   01234"},
   281  	{"1234", "% 8.6d", "  001234"},
   282  	{"-1234", "% 8.3d", "   -1234"},
   283  	{"-1234", "% 8.4d", "   -1234"},
   284  	{"-1234", "% 8.5d", "  -01234"},
   285  	{"-1234", "% 8.6d", " -001234"},
   286  
   287  	{"1234", "%.3x", "4d2"},
   288  	{"1234", "%.4x", "04d2"},
   289  	{"1234", "%.5x", "004d2"},
   290  	{"1234", "%.6x", "0004d2"},
   291  	{"-1234", "%.3x", "-4d2"},
   292  	{"-1234", "%.4x", "-04d2"},
   293  	{"-1234", "%.5x", "-004d2"},
   294  	{"-1234", "%.6x", "-0004d2"},
   295  
   296  	{"1234", "%8.3x", "     4d2"},
   297  	{"1234", "%8.4x", "    04d2"},
   298  	{"1234", "%8.5x", "   004d2"},
   299  	{"1234", "%8.6x", "  0004d2"},
   300  	{"-1234", "%8.3x", "    -4d2"},
   301  	{"-1234", "%8.4x", "   -04d2"},
   302  	{"-1234", "%8.5x", "  -004d2"},
   303  	{"-1234", "%8.6x", " -0004d2"},
   304  
   305  	{"1234", "%+8.3x", "    +4d2"},
   306  	{"1234", "%+8.4x", "   +04d2"},
   307  	{"1234", "%+8.5x", "  +004d2"},
   308  	{"1234", "%+8.6x", " +0004d2"},
   309  	{"-1234", "%+8.3x", "    -4d2"},
   310  	{"-1234", "%+8.4x", "   -04d2"},
   311  	{"-1234", "%+8.5x", "  -004d2"},
   312  	{"-1234", "%+8.6x", " -0004d2"},
   313  
   314  	{"1234", "% 8.3x", "     4d2"},
   315  	{"1234", "% 8.4x", "    04d2"},
   316  	{"1234", "% 8.5x", "   004d2"},
   317  	{"1234", "% 8.6x", "  0004d2"},
   318  	{"1234", "% 8.7x", " 00004d2"},
   319  	{"1234", "% 8.8x", " 000004d2"},
   320  	{"-1234", "% 8.3x", "    -4d2"},
   321  	{"-1234", "% 8.4x", "   -04d2"},
   322  	{"-1234", "% 8.5x", "  -004d2"},
   323  	{"-1234", "% 8.6x", " -0004d2"},
   324  	{"-1234", "% 8.7x", "-00004d2"},
   325  	{"-1234", "% 8.8x", "-000004d2"},
   326  
   327  	{"1234", "%-8.3d", "1234    "},
   328  	{"1234", "%-8.4d", "1234    "},
   329  	{"1234", "%-8.5d", "01234   "},
   330  	{"1234", "%-8.6d", "001234  "},
   331  	{"1234", "%-8.7d", "0001234 "},
   332  	{"1234", "%-8.8d", "00001234"},
   333  	{"-1234", "%-8.3d", "-1234   "},
   334  	{"-1234", "%-8.4d", "-1234   "},
   335  	{"-1234", "%-8.5d", "-01234  "},
   336  	{"-1234", "%-8.6d", "-001234 "},
   337  	{"-1234", "%-8.7d", "-0001234"},
   338  	{"-1234", "%-8.8d", "-00001234"},
   339  
   340  	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
   341  
   342  	{"0", "%.d", ""},
   343  	{"0", "%.0d", ""},
   344  	{"0", "%3.d", ""},
   345  }
   346  
   347  func TestFormat(t *testing.T) {
   348  	for i, test := range formatTests {
   349  		var x *Int
   350  		if test.input != "<nil>" {
   351  			var ok bool
   352  			x, ok = new(Int).SetString(test.input, 0)
   353  			if !ok {
   354  				t.Errorf("#%d failed reading input %s", i, test.input)
   355  			}
   356  		}
   357  		output := fmt.Sprintf(test.format, x)
   358  		if output != test.output {
   359  			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
   360  		}
   361  	}
   362  }
   363  
   364  var scanTests = []struct {
   365  	input     string
   366  	format    string
   367  	output    string
   368  	remaining int
   369  }{
   370  	{"1010", "%b", "10", 0},
   371  	{"0b1010", "%v", "10", 0},
   372  	{"12", "%o", "10", 0},
   373  	{"012", "%v", "10", 0},
   374  	{"10", "%d", "10", 0},
   375  	{"10", "%v", "10", 0},
   376  	{"a", "%x", "10", 0},
   377  	{"0xa", "%v", "10", 0},
   378  	{"A", "%X", "10", 0},
   379  	{"-A", "%X", "-10", 0},
   380  	{"+0b1011001", "%v", "89", 0},
   381  	{"0xA", "%v", "10", 0},
   382  	{"0 ", "%v", "0", 1},
   383  	{"2+3", "%v", "2", 2},
   384  	{"0XABC 12", "%v", "2748", 3},
   385  }
   386  
   387  func TestScan(t *testing.T) {
   388  	var buf bytes.Buffer
   389  	for i, test := range scanTests {
   390  		x := new(Int)
   391  		buf.Reset()
   392  		buf.WriteString(test.input)
   393  		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
   394  			t.Errorf("#%d error: %s", i, err)
   395  		}
   396  		if x.String() != test.output {
   397  			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
   398  		}
   399  		if buf.Len() != test.remaining {
   400  			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
   401  		}
   402  	}
   403  }