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