...

Source file src/math/big/intconv_test.go

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

View as plain text