Home | History | Annotate | Download | only in big
      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: "", ok: false},
     21 	{in: "a", ok: false},
     22 	{in: "z", ok: false},
     23 	{in: "+", ok: false},
     24 	{in: "-", ok: false},
     25 	{in: "0b", ok: false},
     26 	{in: "0x", ok: false},
     27 	{in: "2", base: 2, ok: false},
     28 	{in: "0b2", base: 0, ok: false},
     29 	{in: "08", ok: false},
     30 	{in: "8", base: 8, ok: false},
     31 	{in: "0xg", base: 0, ok: false},
     32 	{in: "g", base: 16, ok: false},
     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, ok: false},
     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 }
     60 
     61 func format(base int) string {
     62 	switch base {
     63 	case 2:
     64 		return "%b"
     65 	case 8:
     66 		return "%o"
     67 	case 16:
     68 		return "%x"
     69 	}
     70 	return "%d"
     71 }
     72 
     73 func TestGetString(t *testing.T) {
     74 	z := new(Int)
     75 	for i, test := range stringTests {
     76 		if !test.ok {
     77 			continue
     78 		}
     79 		z.SetInt64(test.val)
     80 
     81 		if test.base == 10 {
     82 			s := z.String()
     83 			if s != test.out {
     84 				t.Errorf("#%da got %s; want %s", i, s, test.out)
     85 			}
     86 		}
     87 
     88 		s := fmt.Sprintf(format(test.base), z)
     89 		if s != test.out {
     90 			t.Errorf("#%db got %s; want %s", i, s, test.out)
     91 		}
     92 	}
     93 }
     94 
     95 func TestSetString(t *testing.T) {
     96 	tmp := new(Int)
     97 	for i, test := range stringTests {
     98 		// initialize to a non-zero value so that issues with parsing
     99 		// 0 are detected
    100 		tmp.SetInt64(1234567890)
    101 		n1, ok1 := new(Int).SetString(test.in, test.base)
    102 		n2, ok2 := tmp.SetString(test.in, test.base)
    103 		expected := NewInt(test.val)
    104 		if ok1 != test.ok || ok2 != test.ok {
    105 			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
    106 			continue
    107 		}
    108 		if !ok1 {
    109 			if n1 != nil {
    110 				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
    111 			}
    112 			continue
    113 		}
    114 		if !ok2 {
    115 			if n2 != nil {
    116 				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
    117 			}
    118 			continue
    119 		}
    120 
    121 		if ok1 && !isNormalized(n1) {
    122 			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
    123 		}
    124 		if ok2 && !isNormalized(n2) {
    125 			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
    126 		}
    127 
    128 		if n1.Cmp(expected) != 0 {
    129 			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
    130 		}
    131 		if n2.Cmp(expected) != 0 {
    132 			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
    133 		}
    134 	}
    135 }
    136 
    137 var formatTests = []struct {
    138 	input  string
    139 	format string
    140 	output string
    141 }{
    142 	{"<nil>", "%x", "<nil>"},
    143 	{"<nil>", "%#x", "<nil>"},
    144 	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
    145 
    146 	{"10", "%b", "1010"},
    147 	{"10", "%o", "12"},
    148 	{"10", "%d", "10"},
    149 	{"10", "%v", "10"},
    150 	{"10", "%x", "a"},
    151 	{"10", "%X", "A"},
    152 	{"-10", "%X", "-A"},
    153 	{"10", "%y", "%!y(big.Int=10)"},
    154 	{"-10", "%y", "%!y(big.Int=-10)"},
    155 
    156 	{"10", "%#b", "1010"},
    157 	{"10", "%#o", "012"},
    158 	{"10", "%#d", "10"},
    159 	{"10", "%#v", "10"},
    160 	{"10", "%#x", "0xa"},
    161 	{"10", "%#X", "0XA"},
    162 	{"-10", "%#X", "-0XA"},
    163 	{"10", "%#y", "%!y(big.Int=10)"},
    164 	{"-10", "%#y", "%!y(big.Int=-10)"},
    165 
    166 	{"1234", "%d", "1234"},
    167 	{"1234", "%3d", "1234"},
    168 	{"1234", "%4d", "1234"},
    169 	{"-1234", "%d", "-1234"},
    170 	{"1234", "% 5d", " 1234"},
    171 	{"1234", "%+5d", "+1234"},
    172 	{"1234", "%-5d", "1234 "},
    173 	{"1234", "%x", "4d2"},
    174 	{"1234", "%X", "4D2"},
    175 	{"-1234", "%3x", "-4d2"},
    176 	{"-1234", "%4x", "-4d2"},
    177 	{"-1234", "%5x", " -4d2"},
    178 	{"-1234", "%-5x", "-4d2 "},
    179 	{"1234", "%03d", "1234"},
    180 	{"1234", "%04d", "1234"},
    181 	{"1234", "%05d", "01234"},
    182 	{"1234", "%06d", "001234"},
    183 	{"-1234", "%06d", "-01234"},
    184 	{"1234", "%+06d", "+01234"},
    185 	{"1234", "% 06d", " 01234"},
    186 	{"1234", "%-6d", "1234  "},
    187 	{"1234", "%-06d", "1234  "},
    188 	{"-1234", "%-06d", "-1234 "},
    189 
    190 	{"1234", "%.3d", "1234"},
    191 	{"1234", "%.4d", "1234"},
    192 	{"1234", "%.5d", "01234"},
    193 	{"1234", "%.6d", "001234"},
    194 	{"-1234", "%.3d", "-1234"},
    195 	{"-1234", "%.4d", "-1234"},
    196 	{"-1234", "%.5d", "-01234"},
    197 	{"-1234", "%.6d", "-001234"},
    198 
    199 	{"1234", "%8.3d", "    1234"},
    200 	{"1234", "%8.4d", "    1234"},
    201 	{"1234", "%8.5d", "   01234"},
    202 	{"1234", "%8.6d", "  001234"},
    203 	{"-1234", "%8.3d", "   -1234"},
    204 	{"-1234", "%8.4d", "   -1234"},
    205 	{"-1234", "%8.5d", "  -01234"},
    206 	{"-1234", "%8.6d", " -001234"},
    207 
    208 	{"1234", "%+8.3d", "   +1234"},
    209 	{"1234", "%+8.4d", "   +1234"},
    210 	{"1234", "%+8.5d", "  +01234"},
    211 	{"1234", "%+8.6d", " +001234"},
    212 	{"-1234", "%+8.3d", "   -1234"},
    213 	{"-1234", "%+8.4d", "   -1234"},
    214 	{"-1234", "%+8.5d", "  -01234"},
    215 	{"-1234", "%+8.6d", " -001234"},
    216 
    217 	{"1234", "% 8.3d", "    1234"},
    218 	{"1234", "% 8.4d", "    1234"},
    219 	{"1234", "% 8.5d", "   01234"},
    220 	{"1234", "% 8.6d", "  001234"},
    221 	{"-1234", "% 8.3d", "   -1234"},
    222 	{"-1234", "% 8.4d", "   -1234"},
    223 	{"-1234", "% 8.5d", "  -01234"},
    224 	{"-1234", "% 8.6d", " -001234"},
    225 
    226 	{"1234", "%.3x", "4d2"},
    227 	{"1234", "%.4x", "04d2"},
    228 	{"1234", "%.5x", "004d2"},
    229 	{"1234", "%.6x", "0004d2"},
    230 	{"-1234", "%.3x", "-4d2"},
    231 	{"-1234", "%.4x", "-04d2"},
    232 	{"-1234", "%.5x", "-004d2"},
    233 	{"-1234", "%.6x", "-0004d2"},
    234 
    235 	{"1234", "%8.3x", "     4d2"},
    236 	{"1234", "%8.4x", "    04d2"},
    237 	{"1234", "%8.5x", "   004d2"},
    238 	{"1234", "%8.6x", "  0004d2"},
    239 	{"-1234", "%8.3x", "    -4d2"},
    240 	{"-1234", "%8.4x", "   -04d2"},
    241 	{"-1234", "%8.5x", "  -004d2"},
    242 	{"-1234", "%8.6x", " -0004d2"},
    243 
    244 	{"1234", "%+8.3x", "    +4d2"},
    245 	{"1234", "%+8.4x", "   +04d2"},
    246 	{"1234", "%+8.5x", "  +004d2"},
    247 	{"1234", "%+8.6x", " +0004d2"},
    248 	{"-1234", "%+8.3x", "    -4d2"},
    249 	{"-1234", "%+8.4x", "   -04d2"},
    250 	{"-1234", "%+8.5x", "  -004d2"},
    251 	{"-1234", "%+8.6x", " -0004d2"},
    252 
    253 	{"1234", "% 8.3x", "     4d2"},
    254 	{"1234", "% 8.4x", "    04d2"},
    255 	{"1234", "% 8.5x", "   004d2"},
    256 	{"1234", "% 8.6x", "  0004d2"},
    257 	{"1234", "% 8.7x", " 00004d2"},
    258 	{"1234", "% 8.8x", " 000004d2"},
    259 	{"-1234", "% 8.3x", "    -4d2"},
    260 	{"-1234", "% 8.4x", "   -04d2"},
    261 	{"-1234", "% 8.5x", "  -004d2"},
    262 	{"-1234", "% 8.6x", " -0004d2"},
    263 	{"-1234", "% 8.7x", "-00004d2"},
    264 	{"-1234", "% 8.8x", "-000004d2"},
    265 
    266 	{"1234", "%-8.3d", "1234    "},
    267 	{"1234", "%-8.4d", "1234    "},
    268 	{"1234", "%-8.5d", "01234   "},
    269 	{"1234", "%-8.6d", "001234  "},
    270 	{"1234", "%-8.7d", "0001234 "},
    271 	{"1234", "%-8.8d", "00001234"},
    272 	{"-1234", "%-8.3d", "-1234   "},
    273 	{"-1234", "%-8.4d", "-1234   "},
    274 	{"-1234", "%-8.5d", "-01234  "},
    275 	{"-1234", "%-8.6d", "-001234 "},
    276 	{"-1234", "%-8.7d", "-0001234"},
    277 	{"-1234", "%-8.8d", "-00001234"},
    278 
    279 	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
    280 
    281 	{"0", "%.d", ""},
    282 	{"0", "%.0d", ""},
    283 	{"0", "%3.d", ""},
    284 }
    285 
    286 func TestFormat(t *testing.T) {
    287 	for i, test := range formatTests {
    288 		var x *Int
    289 		if test.input != "<nil>" {
    290 			var ok bool
    291 			x, ok = new(Int).SetString(test.input, 0)
    292 			if !ok {
    293 				t.Errorf("#%d failed reading input %s", i, test.input)
    294 			}
    295 		}
    296 		output := fmt.Sprintf(test.format, x)
    297 		if output != test.output {
    298 			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
    299 		}
    300 	}
    301 }
    302 
    303 var scanTests = []struct {
    304 	input     string
    305 	format    string
    306 	output    string
    307 	remaining int
    308 }{
    309 	{"1010", "%b", "10", 0},
    310 	{"0b1010", "%v", "10", 0},
    311 	{"12", "%o", "10", 0},
    312 	{"012", "%v", "10", 0},
    313 	{"10", "%d", "10", 0},
    314 	{"10", "%v", "10", 0},
    315 	{"a", "%x", "10", 0},
    316 	{"0xa", "%v", "10", 0},
    317 	{"A", "%X", "10", 0},
    318 	{"-A", "%X", "-10", 0},
    319 	{"+0b1011001", "%v", "89", 0},
    320 	{"0xA", "%v", "10", 0},
    321 	{"0 ", "%v", "0", 1},
    322 	{"2+3", "%v", "2", 2},
    323 	{"0XABC 12", "%v", "2748", 3},
    324 }
    325 
    326 func TestScan(t *testing.T) {
    327 	var buf bytes.Buffer
    328 	for i, test := range scanTests {
    329 		x := new(Int)
    330 		buf.Reset()
    331 		buf.WriteString(test.input)
    332 		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
    333 			t.Errorf("#%d error: %s", i, err)
    334 		}
    335 		if x.String() != test.output {
    336 			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
    337 		}
    338 		if buf.Len() != test.remaining {
    339 			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
    340 		}
    341 	}
    342 }
    343