github.com/c9s/go@v0.0.0-20180120015821-984e81f64e0c/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 }