Source file
src/math/big/intconv_test.go
1
2
3
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
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
38
39 {in: "_"},
40 {in: "0_"},
41 {in: "_0"},
42 {in: "-1__0"},
43 {in: "0x10_"},
44 {in: "1_000", base: 10},
45 {in: "d_e_a_d", base: 16},
46
47
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
82
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
184
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"},
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