1 // Copyright 2009 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.
13 var cmpTests = []struct {
20 {nat(nil), nat(nil), 0},
25 {nat{0, _M}, nat{1}, 1},
26 {nat{1}, nat{0, _M}, -1},
27 {nat{1, _M}, nat{0, _M}, 1},
28 {nat{0, _M}, nat{1, _M}, -1},
29 {nat{16, 571956, 8794, 68}, nat{837, 9146, 1, 754489}, -1},
30 {nat{34986, 41, 105, 1957}, nat{56, 7458, 104, 1957}, 1},
33 func TestCmp(t *testing.T) {
34 for i, a := range cmpTests {
37 t.Errorf("#%d got r = %v; want %v", i, r, a.r)
42 type funNN func(z, x, y nat) nat
49 {nat{1}, nil, nat{1}},
50 {nat{1111111110}, nat{123456789}, nat{987654321}},
51 {nat{0, 0, 0, 1}, nil, nat{0, 0, 0, 1}},
52 {nat{0, 0, 0, 1111111110}, nat{0, 0, 0, 123456789}, nat{0, 0, 0, 987654321}},
53 {nat{0, 0, 0, 1}, nat{0, 0, _M}, nat{0, 0, 1}},
60 {nat{991}, nat{991}, nat{1}},
61 {nat{991 * 991}, nat{991}, nat{991}},
62 {nat{0, 0, 991 * 991}, nat{0, 991}, nat{0, 991}},
63 {nat{1 * 991, 2 * 991, 3 * 991, 4 * 991}, nat{1, 2, 3, 4}, nat{991}},
64 {nat{4, 11, 20, 30, 20, 11, 4}, nat{1, 2, 3, 4}, nat{4, 3, 2, 1}},
65 // 3^100 * 3^28 = 3^128
67 natFromString("11790184577738583171520872861412518665678211592275841109096961"),
68 natFromString("515377520732011331036461129765621272702107522001"),
69 natFromString("22876792454961"),
71 // z = 111....1 (70000 digits)
72 // x = 10^(99*700) + ... + 10^1400 + 10^700 + 1
73 // y = 111....1 (700 digits, larger than Karatsuba threshold on 32-bit and 64-bit)
75 natFromString(strings.Repeat("1", 70000)),
76 natFromString("1" + strings.Repeat(strings.Repeat("0", 699)+"1", 99)),
77 natFromString(strings.Repeat("1", 700)),
79 // z = 111....1 (20000 digits)
81 // y = 111....1 (10000 digits)
83 natFromString(strings.Repeat("1", 20000)),
84 natFromString("1" + strings.Repeat("0", 9999) + "1"),
85 natFromString(strings.Repeat("1", 10000)),
89 func natFromString(s string) nat {
90 x, _, _, err := nat(nil).scan(strings.NewReader(s), 0, false)
97 func TestSet(t *testing.T) {
98 for _, a := range sumNN {
99 z := nat(nil).set(a.z)
101 t.Errorf("got z = %v; want %v", z, a.z)
106 func testFunNN(t *testing.T, msg string, f funNN, a argNN) {
107 z := f(nil, a.x, a.y)
109 t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, z, a.z)
113 func TestFunNN(t *testing.T) {
114 for _, a := range sumNN {
116 testFunNN(t, "add", nat.add, arg)
118 arg = argNN{a.z, a.y, a.x}
119 testFunNN(t, "add symmetric", nat.add, arg)
121 arg = argNN{a.x, a.z, a.y}
122 testFunNN(t, "sub", nat.sub, arg)
124 arg = argNN{a.y, a.z, a.x}
125 testFunNN(t, "sub symmetric", nat.sub, arg)
128 for _, a := range prodNN {
130 testFunNN(t, "mul", nat.mul, arg)
132 arg = argNN{a.z, a.y, a.x}
133 testFunNN(t, "mul symmetric", nat.mul, arg)
137 var mulRangesN = []struct {
148 {1, 0, "1"}, // empty range
149 {100, 1, "1"}, // empty range
150 {1, 10, "3628800"}, // 10!
151 {1, 20, "2432902008176640000"}, // 20!
153 "933262154439441526816992388562667004907159682643816214685929" +
154 "638952175999932299156089414639761565182862536979208272237582" +
155 "51185210916864000000000000000000000000", // 100!
159 func TestMulRangeN(t *testing.T) {
160 for i, r := range mulRangesN {
161 prod := nat(nil).mulRange(r.a, r.b).decimalString()
163 t.Errorf("#%d: got %s; want %s", i, prod, r.prod)
168 // allocBytes returns the number of bytes allocated by invoking f.
169 func allocBytes(f func()) uint64 {
170 var stats runtime.MemStats
171 runtime.ReadMemStats(&stats)
172 t := stats.TotalAlloc
174 runtime.ReadMemStats(&stats)
175 return stats.TotalAlloc - t
178 // TestMulUnbalanced tests that multiplying numbers of different lengths
179 // does not cause deep recursion and in turn allocate too much memory.
180 // Test case for issue 3807.
181 func TestMulUnbalanced(t *testing.T) {
182 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
185 allocSize := allocBytes(func() {
188 inputSize := uint64(len(x)+len(y)) * _S
189 if ratio := allocSize / uint64(inputSize); ratio > 10 {
190 t.Errorf("multiplication uses too much memory (%d > %d times the size of inputs)", allocSize, ratio)
194 func rndNat(n int) nat {
195 return nat(rndV(n)).norm()
198 func BenchmarkMul(b *testing.B) {
202 for i := 0; i < b.N; i++ {
208 func TestNLZ(t *testing.T) {
210 for i := 0; i <= _W; i++ {
211 if int(nlz(x)) != i {
212 t.Errorf("failed at %x: got %d want %d", x, nlz(x), i)
218 type shiftTest struct {
224 var leftShiftTests = []shiftTest{
229 {nat{1 << (_W - 1)}, 1, nat{0}},
230 {nat{1 << (_W - 1), 0}, 1, nat{0, 1}},
233 func TestShiftLeft(t *testing.T) {
234 for i, test := range leftShiftTests {
236 z = z.shl(test.in, test.shift)
237 for j, d := range test.out {
238 if j >= len(z) || z[j] != d {
239 t.Errorf("#%d: got: %v want: %v", i, z, test.out)
246 var rightShiftTests = []shiftTest{
252 {nat{0, 1}, 1, nat{1 << (_W - 1)}},
253 {nat{2, 1, 1}, 1, nat{1<<(_W-1) + 1, 1 << (_W - 1)}},
256 func TestShiftRight(t *testing.T) {
257 for i, test := range rightShiftTests {
259 z = z.shr(test.in, test.shift)
260 for j, d := range test.out {
261 if j >= len(z) || z[j] != d {
262 t.Errorf("#%d: got: %v want: %v", i, z, test.out)
269 type modWTest struct {
275 var modWTests32 = []modWTest{
276 {"23492635982634928349238759823742", "252341", "220170"},
279 var modWTests64 = []modWTest{
280 {"6527895462947293856291561095690465243862946", "524326975699234", "375066989628668"},
283 func runModWTests(t *testing.T, tests []modWTest) {
284 for i, test := range tests {
285 in, _ := new(Int).SetString(test.in, 10)
286 d, _ := new(Int).SetString(test.dividend, 10)
287 out, _ := new(Int).SetString(test.out, 10)
289 r := in.abs.modW(d.abs[0])
291 t.Errorf("#%d failed: got %d want %s", i, r, out)
296 func TestModW(t *testing.T) {
298 runModWTests(t, modWTests32)
301 runModWTests(t, modWTests64)
305 func TestTrailingZeroBits(t *testing.T) {
306 // test 0 case explicitly
307 if n := trailingZeroBits(0); n != 0 {
308 t.Errorf("got trailingZeroBits(0) = %d; want 0", n)
312 for i := uint(0); i < _W; i++ {
313 n := trailingZeroBits(x)
315 t.Errorf("got trailingZeroBits(%#x) = %d; want %d", x, n, i%_W)
320 // test 0 case explicitly
321 if n := nat(nil).trailingZeroBits(); n != 0 {
322 t.Errorf("got nat(nil).trailingZeroBits() = %d; want 0", n)
325 y := nat(nil).set(natOne)
326 for i := uint(0); i <= 3*_W; i++ {
327 n := y.trailingZeroBits()
329 t.Errorf("got 0x%s.trailingZeroBits() = %d; want %d", y.hexString(), n, i)
335 var montgomeryTests = []struct {
341 "0xffffffffffffffffffffffffffffffffffffffffffffffffe",
342 "0xffffffffffffffffffffffffffffffffffffffffffffffffe",
343 "0xfffffffffffffffffffffffffffffffffffffffffffffffff",
345 "0xffffffffffffffffffffffffffffffffffffffffff",
346 "0xffffffffffffffffffffffffffffffffff",
349 "0x0000000080000000",
350 "0x00000000ffffffff",
351 "0x0000000010000001",
353 "0x0000000088000000",
354 "0x0000000007800001",
357 "0xffffffffffffffffffffffffffffffff00000000000022222223333333333444444444",
358 "0xffffffffffffffffffffffffffffffff999999999999999aaabbbbbbbbcccccccccccc",
359 "0x33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
361 "0x22bb05b6d95eaaeca2bb7c05e51f807bce9064b5fbad177161695e4558f9474e91cd79",
362 "0x14beb58d230f85b6d95eaaeca2bb7c05e51f807bce9064b5fb45669afa695f228e48cd",
365 "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000022222223333333333444444444",
366 "0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff999999999999999aaabbbbbbbbcccccccccccc",
367 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff33377fffffffffffffffffffffffffffffffffffffffffffff0000000000022222eee1",
369 "0x5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d7a11c7772cba02c22f9711078d51a3797eb18e691295293284d988e349fa6deba46b25a4ecd9f715",
370 "0x92fcad4b5c0d52f451aec609b15da8e5e5626c4eaa88723bdeac9d25ca9b961269400410ca208a16af9c2fb07d799c32fe2f3cc5422f9711078d51a3797eb18e691295293284d8f5e69caf6decddfe1df6",
374 func TestMontgomery(t *testing.T) {
375 for i, test := range montgomeryTests {
376 x := natFromString(test.x)
377 y := natFromString(test.y)
378 m := natFromString(test.m)
382 out = natFromString(test.out32)
384 out = natFromString(test.out64)
387 k0 := Word(test.k0 & _M) // mask k0 to ensure that it fits for 32-bit systems.
388 z := nat(nil).montgomery(x, y, m, k0, len(m))
391 t.Errorf("#%d got %s want %s", i, z.decimalString(), out.decimalString())
396 var expNNTests = []struct {
400 {"0", "0", "0", "1"},
401 {"0", "0", "1", "0"},
402 {"1", "1", "1", "0"},
403 {"2", "1", "1", "0"},
404 {"2", "2", "1", "0"},
405 {"10", "100000000000", "1", "0"},
406 {"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
407 {"0x8000000000000000", "2", "6719", "4944"},
408 {"0x8000000000000000", "3", "6719", "5447"},
409 {"0x8000000000000000", "1000", "6719", "1603"},
410 {"0x8000000000000000", "1000000", "6719", "3199"},
412 "2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
413 "298472983472983471903246121093472394872319615612417471234712061",
414 "29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
415 "23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
419 func TestExpNN(t *testing.T) {
420 for i, test := range expNNTests {
421 x := natFromString(test.x)
422 y := natFromString(test.y)
423 out := natFromString(test.out)
427 m = natFromString(test.m)
430 z := nat(nil).expNN(x, y, m)
432 t.Errorf("#%d got %s want %s", i, z.decimalString(), out.decimalString())
437 func ExpHelper(b *testing.B, x, y Word) {
439 for i := 0; i < b.N; i++ {
444 func BenchmarkExp3Power0x10(b *testing.B) { ExpHelper(b, 3, 0x10) }
445 func BenchmarkExp3Power0x40(b *testing.B) { ExpHelper(b, 3, 0x40) }
446 func BenchmarkExp3Power0x100(b *testing.B) { ExpHelper(b, 3, 0x100) }
447 func BenchmarkExp3Power0x400(b *testing.B) { ExpHelper(b, 3, 0x400) }
448 func BenchmarkExp3Power0x1000(b *testing.B) { ExpHelper(b, 3, 0x1000) }
449 func BenchmarkExp3Power0x4000(b *testing.B) { ExpHelper(b, 3, 0x4000) }
450 func BenchmarkExp3Power0x10000(b *testing.B) { ExpHelper(b, 3, 0x10000) }
451 func BenchmarkExp3Power0x40000(b *testing.B) { ExpHelper(b, 3, 0x40000) }
452 func BenchmarkExp3Power0x100000(b *testing.B) { ExpHelper(b, 3, 0x100000) }
453 func BenchmarkExp3Power0x400000(b *testing.B) { ExpHelper(b, 3, 0x400000) }
455 func fibo(n int) nat {
465 for i := 1; i < n; i++ {
467 f0, f1, f2 = f1, f2, f0
472 var fiboNums = []string{
482 "2880067194370816120",
483 "354224848179261915075",
486 func TestFibo(t *testing.T) {
487 for i, want := range fiboNums {
489 got := fibo(n).decimalString()
491 t.Errorf("fibo(%d) failed: got %s want %s", n, got, want)
496 func BenchmarkFibo(b *testing.B) {
497 for i := 0; i < b.N; i++ {
507 var bitTests = []struct {
522 {"0x8000000000000000", 62, 0},
523 {"0x8000000000000000", 63, 1},
524 {"0x8000000000000000", 64, 0},
526 {"0x3" + strings.Repeat("0", 32), 127, 0},
527 {"0x3" + strings.Repeat("0", 32), 128, 1},
528 {"0x3" + strings.Repeat("0", 32), 129, 1},
529 {"0x3" + strings.Repeat("0", 32), 130, 0},
532 func TestBit(t *testing.T) {
533 for i, test := range bitTests {
534 x := natFromString(test.x)
535 if got := x.bit(test.i); got != test.want {
536 t.Errorf("#%d: %s.bit(%d) = %v; want %v", i, test.x, test.i, got, test.want)
541 var stickyTests = []struct {
557 {"0x8000000000000000", 63, 0},
558 {"0x8000000000000000", 64, 1},
560 {"0x1" + strings.Repeat("0", 100), 400, 0},
561 {"0x1" + strings.Repeat("0", 100), 401, 1},
564 func TestSticky(t *testing.T) {
565 for i, test := range stickyTests {
566 x := natFromString(test.x)
567 if got := x.sticky(test.i); got != test.want {
568 t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i, got, test.want)
571 // all subsequent i's should also return 1
572 for d := uint(1); d <= 3; d++ {
573 if got := x.sticky(test.i + d); got != 1 {
574 t.Errorf("#%d: %s.sticky(%d) = %v; want %v", i, test.x, test.i+d, got, 1)