github.com/cznic/mathutil@v0.0.0-20181122101859-297441e03548/mersenne/all_test.go (about) 1 // Copyright (c) 2014 The mersenne 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 mersenne 6 7 import ( 8 "math" 9 "math/big" 10 "math/rand" 11 "runtime" 12 "sync" 13 "testing" 14 15 "github.com/cznic/mathutil" 16 ) 17 18 func r32() *mathutil.FC32 { 19 r, err := mathutil.NewFC32(math.MinInt32, math.MaxInt32, true) 20 if err != nil { 21 panic(err) 22 } 23 24 return r 25 } 26 27 var ( 28 r64lo = big.NewInt(math.MinInt64) 29 r64hi = big.NewInt(math.MaxInt64) 30 ) 31 32 func r64() *mathutil.FCBig { 33 r, err := mathutil.NewFCBig(r64lo, r64hi, true) 34 if err != nil { 35 panic(err) 36 } 37 38 return r 39 } 40 41 func TestNew(t *testing.T) { 42 const N = 1e4 43 data := []struct{ n, m uint32 }{ 44 {0, 0}, 45 {1, 1}, 46 {2, 3}, 47 {3, 7}, 48 {4, 15}, 49 {5, 31}, 50 {6, 63}, 51 {7, 127}, 52 {8, 255}, 53 {9, 511}, 54 {10, 1023}, 55 {11, 2047}, 56 {12, 4095}, 57 {13, 8191}, 58 {14, 16383}, 59 {15, 32767}, 60 {16, 65535}, 61 {17, 131071}, 62 } 63 64 e := big.NewInt(0) 65 for _, v := range data { 66 g := New(v.n) 67 e.SetInt64(int64(v.m)) 68 if g.Cmp(e) != 0 { 69 t.Errorf("%d: got %s, exp %s", v.n, g, e) 70 } 71 } 72 73 r := r32() 74 for i := 0; i < N; i++ { 75 exp := uint32(r.Next()) % 1e6 76 g := New(exp) 77 b0 := g.BitLen() 78 g.Add(g, _1) 79 b1 := g.BitLen() 80 if b1-b0 != 1 { 81 t.Fatal(i, exp, b1, b0) 82 } 83 } 84 } 85 86 func benchmarkNew(b *testing.B, max uint32) { 87 const N = 1 << 16 88 b.StopTimer() 89 a := make([]uint32, N) 90 r := r32() 91 for i := range a { 92 a[i] = uint32(r.Next()) % max 93 } 94 runtime.GC() 95 b.StartTimer() 96 for i := 0; i < b.N; i++ { 97 New(a[i&(N-1)]) 98 } 99 } 100 101 func BenchmarkNew_1e1(b *testing.B) { 102 benchmarkNew(b, 1e1) 103 } 104 105 func BenchmarkNew_1e2(b *testing.B) { 106 benchmarkNew(b, 1e2) 107 } 108 109 func BenchmarkNew_1e3(b *testing.B) { 110 benchmarkNew(b, 1e3) 111 } 112 113 func BenchmarkNew_1e4(b *testing.B) { 114 benchmarkNew(b, 1e4) 115 } 116 117 func BenchmarkNew_1e5(b *testing.B) { 118 benchmarkNew(b, 1e5) 119 } 120 121 func BenchmarkNew_1e6(b *testing.B) { 122 benchmarkNew(b, 1e6) 123 } 124 125 func BenchmarkNew_1e7(b *testing.B) { 126 benchmarkNew(b, 1e7) 127 } 128 129 func BenchmarkNew_1e8(b *testing.B) { 130 benchmarkNew(b, 1e8) 131 } 132 133 func TestHasFactorUint32(t *testing.T) { 134 data := []struct { 135 d, e uint32 136 r bool 137 }{ 138 {0, 42, false}, 139 {1, 24, true}, 140 {2, 22, false}, 141 {3, 2, true}, 142 {3, 3, false}, 143 {3, 4, true}, 144 {3, 5, false}, 145 {3, 6, true}, 146 {5, 4, true}, 147 {5, 5, false}, 148 {5, 6, false}, 149 {5, 7, false}, 150 {5, 8, true}, 151 {5, 9, false}, 152 {5, 10, false}, 153 {5, 11, false}, 154 {5, 12, true}, 155 {7, 3, true}, 156 {7, 6, true}, 157 {7, 9, true}, 158 {9, 6, true}, 159 {9, 12, true}, 160 {9, 18, true}, 161 {11, 10, true}, 162 {23, 11, true}, 163 {89, 11, true}, 164 {47, 23, true}, 165 {193707721, 67, true}, 166 {13007, 929, true}, 167 {264248689, 500471, true}, 168 {112027889, 1000249, true}, 169 {252079759, 2000633, true}, 170 {222054983, 3000743, true}, 171 {1920355681, 4000741, true}, 172 {330036367, 5000551, true}, 173 {1020081431, 6000479, true}, 174 {840074281, 7000619, true}, 175 {624031279, 8000401, true}, 176 {378031207, 9000743, true}, 177 {380036519, 10000961, true}, 178 {40001447, 20000723, true}, 179 } 180 181 for _, v := range data { 182 if g, e := HasFactorUint32(v.d, v.e), v.r; g != e { 183 t.Errorf("d %d e %d: got %t, exp %t", v.d, v.e, g, e) 184 } 185 } 186 } 187 188 func TestHasFactorUint64(t *testing.T) { 189 data := []struct { 190 d uint64 191 e uint32 192 r bool 193 }{ 194 {0, 42, false}, 195 {1, 24, true}, 196 {2, 22, false}, 197 {3, 2, true}, 198 {3, 3, false}, 199 {3, 4, true}, 200 {3, 5, false}, 201 {3, 6, true}, 202 {5, 4, true}, 203 {5, 5, false}, 204 {5, 6, false}, 205 {5, 7, false}, 206 {5, 8, true}, 207 {5, 9, false}, 208 {5, 10, false}, 209 {5, 11, false}, 210 {5, 12, true}, 211 {7, 3, true}, 212 {7, 6, true}, 213 {7, 9, true}, 214 {9, 6, true}, 215 {9, 12, true}, 216 {9, 18, true}, 217 {11, 10, true}, 218 {23, 11, true}, 219 {89, 11, true}, 220 {47, 23, true}, 221 {193707721, 67, true}, 222 {13007, 929, true}, 223 {264248689, 500471, true}, 224 {112027889, 1000249, true}, 225 {252079759, 2000633, true}, 226 {222054983, 3000743, true}, 227 {1920355681, 4000741, true}, 228 {330036367, 5000551, true}, 229 {1020081431, 6000479, true}, 230 {840074281, 7000619, true}, 231 {624031279, 8000401, true}, 232 {378031207, 9000743, true}, 233 {380036519, 10000961, true}, 234 {40001447, 20000723, true}, 235 {1872347344039, 1000099, true}, 236 } 237 238 for _, v := range data { 239 if g, e := HasFactorUint64(v.d, v.e), v.r; g != e { 240 t.Errorf("d %d e %d: got %t, exp %t", v.d, v.e, g, e) 241 } 242 } 243 } 244 245 func TestHasFactorBigInt(t *testing.T) { 246 data := []struct { 247 d interface{} 248 e uint32 249 r bool 250 }{ 251 {0, 42, false}, 252 {1, 24, true}, 253 {2, 22, false}, 254 {3, 2, true}, 255 {3, 3, false}, 256 {3, 4, true}, 257 {3, 5, false}, 258 {3, 6, true}, 259 {5, 4, true}, 260 {5, 5, false}, 261 {5, 6, false}, 262 {5, 7, false}, 263 {5, 8, true}, 264 {5, 9, false}, 265 {5, 10, false}, 266 {5, 11, false}, 267 {5, 12, true}, 268 {7, 3, true}, 269 {7, 6, true}, 270 {7, 9, true}, 271 {9, 6, true}, 272 {9, 12, true}, 273 {9, 18, true}, 274 {11, 10, true}, 275 {23, 11, true}, 276 {89, 11, true}, 277 {47, 23, true}, 278 {193707721, 67, true}, 279 {13007, 929, true}, 280 {264248689, 500471, true}, 281 {112027889, 1000249, true}, 282 {252079759, 2000633, true}, 283 {222054983, 3000743, true}, 284 {1920355681, 4000741, true}, 285 {330036367, 5000551, true}, 286 {1020081431, 6000479, true}, 287 {840074281, 7000619, true}, 288 {624031279, 8000401, true}, 289 {378031207, 9000743, true}, 290 {380036519, 10000961, true}, 291 {40001447, 20000723, true}, 292 {"1872347344039", 1000099, true}, 293 {"11502865265922183403581252152383", 100279, true}, 294 {"533975545077050000610542659519277030089249998649", 7293457, true}, 295 } 296 297 var d big.Int 298 for _, v := range data { 299 bigInt(&d, v.d) 300 if g, e := HasFactorBigInt(&d, v.e), v.r; g != e { 301 t.Errorf("d %s e %d: got %t, exp %t", &d, v.e, g, e) 302 } 303 304 if g, e := HasFactorBigInt2(&d, big.NewInt(int64(v.e))), v.r; g != e { 305 t.Errorf("d %s e %d: got %t, exp %t", &d, v.e, g, e) 306 } 307 } 308 } 309 310 var once309 sync.Once 311 312 func BenchmarkHasFactorUint32Rnd(b *testing.B) { 313 const N = 1 << 16 314 b.StopTimer() 315 type t struct{ d, e uint32 } 316 a := make([]t, N) 317 r := r32() 318 for i := range a { 319 a[i] = t{ 320 uint32(r.Next()) | 1, 321 uint32(r.Next()), 322 } 323 } 324 once309.Do(func() { b.Log("Random 32 bit factor, random 32 bit exponent\n") }) 325 runtime.GC() 326 b.StartTimer() 327 for i := 0; i < b.N; i++ { 328 v := a[i&(N-1)] 329 HasFactorUint32(v.d, v.e) 330 } 331 } 332 333 var once332 sync.Once 334 335 func BenchmarkHasFactorUint64Rnd(b *testing.B) { 336 const N = 1 << 16 337 b.StopTimer() 338 type t struct { 339 d uint64 340 e uint32 341 } 342 a := make([]t, N) 343 r := r64() 344 for i := range a { 345 a[i] = t{ 346 uint64(r.Next().Int64()) | 1, 347 uint32(r.Next().Int64()), 348 } 349 } 350 once332.Do(func() { b.Log("Random 64 bit factor, random 32 bit exponent\n") }) 351 runtime.GC() 352 b.StartTimer() 353 for i := 0; i < b.N; i++ { 354 v := a[i&(N-1)] 355 HasFactorUint64(v.d, v.e) 356 } 357 } 358 359 var once358 sync.Once 360 361 func BenchmarkHasFactorBigIntRnd_128b(b *testing.B) { 362 const N = 1 << 16 363 b.StopTimer() 364 type t struct { 365 d *big.Int 366 e uint32 367 } 368 a := make([]t, N) 369 r, err := mathutil.NewFCBig(_1, New(128), true) 370 if err != nil { 371 b.Fatal(err) 372 } 373 r2 := r32() 374 for i := range a { 375 dd := r.Next() 376 a[i] = t{ 377 dd.SetBit(dd, 0, 1), 378 uint32(r2.Next()), 379 } 380 } 381 once358.Do(func() { b.Log("Random 128 bit factor, random 32 bit exponent\n") }) 382 runtime.GC() 383 b.StartTimer() 384 for i := 0; i < b.N; i++ { 385 v := a[i&(N-1)] 386 HasFactorBigInt(v.d, v.e) 387 } 388 } 389 390 var ( 391 f104b, _ = big.NewInt(0).SetString( // 104 bit factor of M100279 392 "11502865265922183403581252152383", 393 10, 394 ) 395 f137b, _ = big.NewInt(0).SetString( // 137 bit factor of M7293457 396 "533975545077050000610542659519277030089249998649", 397 10, 398 ) 399 ) 400 401 var once396 sync.Once 402 403 func BenchmarkHasFactorBigInt_104b(b *testing.B) { 404 b.StopTimer() 405 once396.Do(func() { b.Log("Verify a 104 bit factor of M100279 (16.6 bit exponent)\n") }) 406 runtime.GC() 407 var r bool 408 b.StartTimer() 409 for i := 0; i < b.N; i++ { 410 r = HasFactorBigInt(f104b, 100279) 411 } 412 if !r { 413 b.Fatal(r) 414 } 415 } 416 417 var once412 sync.Once 418 419 func BenchmarkHasFactorBigIntMod104b(b *testing.B) { 420 b.StopTimer() 421 once412.Do(func() { b.Log("Verify a 104 bit factor of M100279 (16.6 bit exponent) using big.Int.Mod\n") }) 422 runtime.GC() 423 m := New(100279) 424 var x big.Int 425 b.StartTimer() 426 for i := 0; i < b.N; i++ { 427 x.Mod(m, f104b) 428 } 429 if x.Cmp(_0) != 0 { 430 b.Fatal(x) 431 } 432 } 433 434 var once429 sync.Once 435 436 func BenchmarkHasFactorBigInt_137b(b *testing.B) { 437 b.StopTimer() 438 once429.Do(func() { b.Log("Verify a 137 bit factor of M7293457 (22.8 bit exponent)\n") }) 439 runtime.GC() 440 var r bool 441 b.StartTimer() 442 for i := 0; i < b.N; i++ { 443 r = HasFactorBigInt(f137b, 7293457) 444 } 445 if !r { 446 b.Fatal(r) 447 } 448 } 449 450 var once445 sync.Once 451 452 func BenchmarkHasFactorBigIntMod137b(b *testing.B) { 453 b.StopTimer() 454 once445.Do(func() { b.Log("Verify a 137 bit factor of M7293457 (22.8 bit exponent) using big.Int.Mod\n") }) 455 runtime.GC() 456 m := New(7293457) 457 var x big.Int 458 b.StartTimer() 459 for i := 0; i < b.N; i++ { 460 x.Mod(m, f137b) 461 } 462 if x.Cmp(_0) != 0 { 463 b.Fatal(x) 464 } 465 } 466 467 func bigInt(b *big.Int, v interface{}) { 468 switch v := v.(type) { 469 case int: 470 b.SetInt64(int64(v)) 471 case string: 472 if _, ok := b.SetString(v, 10); !ok { 473 panic("bigInt: bad decimal string") 474 } 475 default: 476 panic("bigInt: bad v.(type)") 477 } 478 } 479 480 func TestFromFactorBigInt(t *testing.T) { 481 data := []struct { 482 d interface{} 483 n uint32 484 }{ 485 {0, 0}, 486 {1, 1}, 487 {2, 0}, 488 {3, 2}, 489 {4, 0}, 490 {5, 4}, 491 {7, 3}, 492 {9, 6}, 493 {11, 10}, 494 {23, 11}, 495 {89, 11}, 496 {"7432339208719", 101}, 497 {"198582684439", 1009}, 498 {"20649907789079", 1009}, 499 {"21624641697047", 1009}, 500 {"30850253615723594284324529", 1009}, 501 {"1134327302421596486779379019599", 1009}, 502 {35311753, 10009}, 503 {"104272300687", 10009}, 504 {"10409374085465521", 10009}, 505 {"890928517778601397463", 10009}, 506 {6400193, 100003}, 507 } 508 509 f := func(d *big.Int, max, e uint32) { 510 if g := FromFactorBigInt(d, max); g != e { 511 t.Fatalf("%s %d %d %d", d, max, g, e) 512 } 513 } 514 515 var d big.Int 516 for _, v := range data { 517 bigInt(&d, v.d) 518 switch { 519 case v.n > 0: 520 f(&d, v.n-1, 0) 521 default: // v.n == 0 522 f(&d, 100, 0) 523 } 524 f(&d, v.n, v.n) 525 } 526 } 527 528 var f20b = big.NewInt(200000447) // 20 bit factor of M100000223 529 530 func benchmarkFromFactorBigInt(b *testing.B, f *big.Int, max uint32) { 531 var n uint32 532 for i := 0; i < b.N; i++ { 533 n = FromFactorBigInt(f, max) 534 } 535 if n != 0 { 536 b.Fatal(n) 537 } 538 } 539 540 func BenchmarkFromFactorBigInt20b_1e1(b *testing.B) { 541 benchmarkFromFactorBigInt(b, f20b, 1e1) 542 } 543 544 func BenchmarkFromFactorBigInt20b_1e2(b *testing.B) { 545 benchmarkFromFactorBigInt(b, f20b, 1e2) 546 } 547 548 func BenchmarkFromFactorBigInt20b_1e3(b *testing.B) { 549 benchmarkFromFactorBigInt(b, f20b, 1e3) 550 } 551 552 func BenchmarkFromFactorBigInt20b_1e4(b *testing.B) { 553 benchmarkFromFactorBigInt(b, f20b, 1e4) 554 } 555 556 func BenchmarkFromFactorBigInt20b_1e5(b *testing.B) { 557 benchmarkFromFactorBigInt(b, f20b, 1e5) 558 } 559 560 func BenchmarkFromFactorBigInt20b_1e6(b *testing.B) { 561 benchmarkFromFactorBigInt(b, f20b, 1e6) 562 } 563 564 func BenchmarkFromFactorBigInt137b_1e1(b *testing.B) { 565 benchmarkFromFactorBigInt(b, f137b, 1e1) 566 } 567 568 func BenchmarkFromFactorBigInt137b_1e2(b *testing.B) { 569 benchmarkFromFactorBigInt(b, f137b, 1e2) 570 } 571 572 func BenchmarkFromFactorBigInt137b_1e3(b *testing.B) { 573 benchmarkFromFactorBigInt(b, f137b, 1e3) 574 } 575 576 func BenchmarkFromFactorBigInt137b_1e4(b *testing.B) { 577 benchmarkFromFactorBigInt(b, f137b, 1e4) 578 } 579 580 func BenchmarkFromFactorBigInt137b_1e5(b *testing.B) { 581 benchmarkFromFactorBigInt(b, f137b, 1e5) 582 } 583 584 func BenchmarkFromFactorBigInt137b_1e6(b *testing.B) { 585 benchmarkFromFactorBigInt(b, f137b, 1e6) 586 } 587 func TestMod(t *testing.T) { 588 const N = 1e4 589 data := []struct { 590 mod, n int64 591 exp uint32 592 }{ 593 {0, 0x00, 3}, 594 {1, 0x01, 3}, 595 {3, 0x03, 3}, 596 {0, 0x07, 3}, 597 {1, 0x0f, 3}, 598 {3, 0x1f, 3}, 599 {0, 0x3f, 3}, 600 {1, 0x7f, 3}, 601 {3, 0xff, 3}, 602 {0, 0x1ff, 3}, 603 } 604 605 var mod, n big.Int 606 for _, v := range data { 607 n.SetInt64(v.n) 608 p := Mod(&mod, &n, v.exp) 609 if p != &mod { 610 t.Fatal(p) 611 } 612 613 if g, e := mod.Int64(), v.mod; g != e { 614 t.Fatal(v.n, v.exp, g, e) 615 } 616 } 617 618 f := func(in int64, exp uint32) { 619 n.SetInt64(in) 620 mod.Mod(&n, New(exp)) 621 e := mod.Int64() 622 Mod(&mod, &n, exp) 623 g := mod.Int64() 624 if g != e { 625 t.Fatal(in, exp, g, e) 626 } 627 } 628 629 r32, _ := mathutil.NewFC32(1, 1e6, true) 630 r64, _ := mathutil.NewFCBig(_0, big.NewInt(math.MaxInt64), true) 631 for i := 0; i < N; i++ { 632 f(r64.Next().Int64(), uint32(r32.Next())) 633 } 634 } 635 636 func benchmarkMod(b *testing.B, w, exp uint32) { 637 b.StopTimer() 638 var n, mod big.Int 639 n.Rand(rand.New(rand.NewSource(1)), New(w)) 640 n.SetBit(&n, int(w), 1) 641 runtime.GC() 642 b.StartTimer() 643 for i := 0; i < b.N; i++ { 644 Mod(&mod, &n, exp) 645 } 646 } 647 648 func benchmarkModBig(b *testing.B, w, exp uint32) { 649 b.StopTimer() 650 var n, mod big.Int 651 n.Rand(rand.New(rand.NewSource(1)), New(w)) 652 n.SetBit(&n, int(w), 1) 653 runtime.GC() 654 runtime.GC() 655 b.StartTimer() 656 for i := 0; i < b.N; i++ { 657 mod.Mod(&n, New(exp)) 658 } 659 } 660 661 func BenchmarkMod_1e2(b *testing.B) { 662 benchmarkMod(b, 1e2+2, 1e2) 663 } 664 665 func BenchmarkModBig_1e2(b *testing.B) { 666 benchmarkModBig(b, 1e2+2, 1e2) 667 } 668 669 func BenchmarkMod_1e3(b *testing.B) { 670 benchmarkMod(b, 1e3+2, 1e3) 671 } 672 673 func BenchmarkModBig_1e3(b *testing.B) { 674 benchmarkModBig(b, 1e3+2, 1e3) 675 } 676 677 func BenchmarkMod_1e4(b *testing.B) { 678 benchmarkMod(b, 1e4+2, 1e4) 679 } 680 681 func BenchmarkModBig_1e4(b *testing.B) { 682 benchmarkModBig(b, 1e4+2, 1e4) 683 } 684 685 func BenchmarkMod_1e5(b *testing.B) { 686 benchmarkMod(b, 1e5+2, 1e5) 687 } 688 689 func BenchmarkModBig_1e5(b *testing.B) { 690 benchmarkModBig(b, 1e5+2, 1e5) 691 } 692 693 func BenchmarkMod_1e6(b *testing.B) { 694 benchmarkMod(b, 1e6+2, 1e6) 695 } 696 697 func BenchmarkModBig_1e6(b *testing.B) { 698 benchmarkModBig(b, 1e6+2, 1e6) 699 } 700 701 func BenchmarkMod_1e7(b *testing.B) { 702 benchmarkMod(b, 1e7+2, 1e7) 703 } 704 705 func BenchmarkModBig_1e7(b *testing.B) { 706 benchmarkModBig(b, 1e7+2, 1e7) 707 } 708 709 func BenchmarkMod_1e8(b *testing.B) { 710 benchmarkMod(b, 1e8+2, 1e8) 711 } 712 713 func BenchmarkModBig_1e8(b *testing.B) { 714 benchmarkModBig(b, 1e8+2, 1e8) 715 } 716 717 func BenchmarkMod_5e8(b *testing.B) { 718 benchmarkMod(b, 5e8+2, 5e8) 719 } 720 721 func BenchmarkModBig_5e8(b *testing.B) { 722 benchmarkModBig(b, 5e8+2, 5e8) 723 } 724 725 func TestModPow(t *testing.T) { 726 const N = 2e2 727 data := []struct{ b, e, m, r uint32 }{ 728 {0, 1, 1, 0}, 729 {0, 2, 1, 0}, 730 {0, 3, 1, 0}, 731 732 {1, 0, 1, 0}, 733 {1, 1, 1, 0}, 734 {1, 2, 1, 0}, 735 {1, 3, 1, 0}, 736 737 {2, 0, 1, 0}, 738 {2, 1, 1, 0}, 739 {2, 2, 1, 0}, 740 {2, 3, 1, 0}, 741 742 {2, 3, 4, 8}, 743 {2, 3, 5, 4}, 744 {2, 4, 3, 1}, 745 {3, 3, 3, 3}, 746 {3, 4, 5, 30}, 747 } 748 749 f := func(b, e, m uint32, expect *big.Int) { 750 got := ModPow(b, e, m) 751 if got.Cmp(expect) != 0 { 752 t.Fatal(b, e, m, got, expect) 753 } 754 } 755 756 var r big.Int 757 for _, v := range data { 758 r.SetInt64(int64(v.r)) 759 f(v.b, v.e, v.m, &r) 760 } 761 762 rg, _ := mathutil.NewFC32(2, 1<<10, true) 763 var bb big.Int 764 for i := 0; i < N; i++ { 765 b, e, m := uint32(rg.Next()), uint32(rg.Next()), uint32(rg.Next()) 766 bb.SetInt64(int64(b)) 767 f(b, e, m, mathutil.ModPowBigInt(&bb, New(e), New(m))) 768 } 769 } 770 771 func benchmarkModPow2(b *testing.B, e, m uint32) { 772 b.StopTimer() 773 runtime.GC() 774 b.StartTimer() 775 for i := 0; i < b.N; i++ { 776 ModPow2(e, m) 777 } 778 } 779 780 func benchmarkModPow(b *testing.B, base, e, m uint32) { 781 b.StopTimer() 782 runtime.GC() 783 b.StartTimer() 784 for i := 0; i < b.N; i++ { 785 ModPow(base, e, m) 786 } 787 } 788 789 func benchmarkModPowBig(b *testing.B, base, e, m uint32) { 790 b.StopTimer() 791 bb := big.NewInt(int64(base)) 792 ee := New(e) 793 mm := New(m) 794 runtime.GC() 795 b.StartTimer() 796 for i := 0; i < b.N; i++ { 797 mathutil.ModPowBigInt(bb, ee, mm) 798 } 799 } 800 801 func BenchmarkModPow2_1e2(b *testing.B) { 802 benchmarkModPow2(b, 1e2, 1e2+1) 803 } 804 805 func BenchmarkModPow_2_1e2(b *testing.B) { 806 benchmarkModPow(b, 2, 1e2, 1e2+1) 807 } 808 809 func BenchmarkModPowB_2_1e2(b *testing.B) { 810 benchmarkModPowBig(b, 2, 1e2, 1e2+1) 811 } 812 813 func BenchmarkModPow_3_1e2(b *testing.B) { 814 benchmarkModPow(b, 3, 1e2, 1e2+1) 815 } 816 817 func BenchmarkModPowB_3_1e2(b *testing.B) { 818 benchmarkModPowBig(b, 3, 1e2, 1e2+1) 819 } 820 821 // ---- 822 823 func BenchmarkModPow2_1e3(b *testing.B) { 824 benchmarkModPow2(b, 1e3, 1e3+1) 825 } 826 827 func BenchmarkModPow_2_1e3(b *testing.B) { 828 benchmarkModPow(b, 2, 1e3, 1e3+1) 829 } 830 831 func BenchmarkModPowB_2_1e3(b *testing.B) { 832 benchmarkModPowBig(b, 2, 1e3, 1e3+1) 833 } 834 835 func BenchmarkModPow_3_1e3(b *testing.B) { 836 benchmarkModPow(b, 3, 1e3, 1e3+1) 837 } 838 839 func BenchmarkModPowB_3_1e3(b *testing.B) { 840 benchmarkModPowBig(b, 3, 1e3, 1e3+1) 841 } 842 843 // ---- 844 845 func BenchmarkModPow2_1e4(b *testing.B) { 846 benchmarkModPow2(b, 1e4, 1e4+1) 847 } 848 849 func BenchmarkModPow_2_1e4(b *testing.B) { 850 benchmarkModPow(b, 2, 1e4, 1e4+1) 851 } 852 853 func BenchmarkModPowB_2_1e4(b *testing.B) { 854 benchmarkModPowBig(b, 2, 1e4, 1e4+1) 855 } 856 857 func BenchmarkModPow_3_1e4(b *testing.B) { 858 benchmarkModPow(b, 3, 1e4, 1e4+1) 859 } 860 861 func BenchmarkModPowB_3_1e4(b *testing.B) { 862 benchmarkModPowBig(b, 3, 1e4, 1e4+1) 863 } 864 865 // ---- 866 867 func BenchmarkModPow2_1e5(b *testing.B) { 868 benchmarkModPow2(b, 1e5, 1e5+1) 869 } 870 871 func BenchmarkModPow2_1e6(b *testing.B) { 872 benchmarkModPow2(b, 1e6, 1e6+1) 873 } 874 875 func BenchmarkModPow2_1e7(b *testing.B) { 876 benchmarkModPow2(b, 1e7, 1e7+1) 877 } 878 879 func BenchmarkModPow2_1e8(b *testing.B) { 880 benchmarkModPow2(b, 1e8, 1e8+1) 881 } 882 883 func BenchmarkModPow2_1e9(b *testing.B) { 884 benchmarkModPow2(b, 1e9, 1e9+1) 885 } 886 887 func TestModPow2(t *testing.T) { 888 const N = 1e3 889 data := []struct{ e, m uint32 }{ 890 // e == 0 -> x == 0 891 {0, 2}, 892 {0, 3}, 893 {0, 4}, 894 895 {1, 2}, 896 {1, 3}, 897 {1, 4}, 898 {1, 5}, 899 900 {2, 2}, 901 {2, 3}, 902 {2, 4}, 903 {2, 5}, 904 905 {3, 2}, 906 {3, 3}, 907 {3, 4}, 908 {3, 5}, 909 {3, 6}, 910 {3, 7}, 911 {3, 8}, 912 {3, 9}, 913 914 {4, 2}, 915 {4, 3}, 916 {4, 4}, 917 {4, 5}, 918 {4, 6}, 919 {4, 7}, 920 {4, 8}, 921 {4, 9}, 922 } 923 924 var got big.Int 925 f := func(e, m uint32) { 926 x := ModPow2(e, m) 927 exp := ModPow(2, e, m) 928 got.SetInt64(0) 929 got.SetBit(&got, int(x), 1) 930 if got.Cmp(exp) != 0 { 931 t.Fatalf("\ne %d, m %d\ng: %s\ne: %s", e, m, &got, exp) 932 } 933 } 934 935 for _, v := range data { 936 f(v.e, v.m) 937 } 938 939 rg, _ := mathutil.NewFC32(2, 1<<10, true) 940 for i := 0; i < N; i++ { 941 f(uint32(rg.Next()), uint32(rg.Next())) 942 } 943 }