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  }