Added helper methods for big ints.

This commit is contained in:
Sander Schobers 2019-12-21 12:53:57 +01:00
parent 39cef02092
commit f6bf5ba60d
3 changed files with 128 additions and 0 deletions

13
ints/big.go Normal file
View File

@ -0,0 +1,13 @@
package ints
import "math/big"
func CopyBig(i *big.Int) *big.Int { return (&big.Int{}).Set(i) }
func DivBig(x, y *big.Int) *big.Int { return x.Div(x, y) }
func MulBig(x, y *big.Int) *big.Int { return x.Mul(x, y) }
func PowTenBig(p int) *big.Int { return Big.PowTen(p) }
func RepunitBig(k int) *big.Int { return Big.Repunit(k) }

17
ints/big_test.go Normal file
View File

@ -0,0 +1,17 @@
package ints
import (
"testing"
)
func BenchmarkIntsSmallRepunit(b *testing.B) {
for i := 0; i < b.N; i++ {
Big.Repunit(1234)
}
}
func BenchmarkIntsLargeRepunit(b *testing.B) {
for i := 0; i < b.N; i++ {
Big.Repunit(1234567)
}
}

98
ints/bignumbers.go Normal file
View File

@ -0,0 +1,98 @@
package ints
import "math/big"
type BigNumbers struct {
Zero *big.Int
One *big.Int
Two *big.Int
Nine *big.Int
Ten *big.Int
Thousand *big.Int
Million *big.Int
Ten10 *big.Int
Ten30 *big.Int
Ten100 *big.Int
Ten300 *big.Int
Ten1000 *big.Int
Ten3000 *big.Int
Ten10000 *big.Int
Ten30000 *big.Int
Ten100000 *big.Int
Ten300000 *big.Int
Ten1000000 *big.Int
}
var Big *BigNumbers = NewBigNumbers()
func NewBigNumbers() *BigNumbers {
ten := big.NewInt(10)
thousand := big.NewInt(1000)
million := big.NewInt(1000000)
ten10 := MulBig(MulBig(MulBig(big.NewInt(1), million), thousand), ten)
ten30 := MulBig(MulBig(MulBig(big.NewInt(1), ten10), ten10), ten10)
ten100 := MulBig(MulBig(MulBig(MulBig(big.NewInt(1), ten30), ten30), ten30), ten10)
ten300 := MulBig(MulBig(MulBig(big.NewInt(1), ten100), ten100), ten100)
ten1000 := MulBig(MulBig(MulBig(MulBig(big.NewInt(1), ten300), ten300), ten300), ten100)
ten3000 := MulBig(MulBig(MulBig(big.NewInt(1), ten1000), ten1000), ten1000)
ten10000 := MulBig(MulBig(MulBig(MulBig(big.NewInt(1), ten3000), ten3000), ten3000), ten1000)
ten30000 := MulBig(MulBig(MulBig(big.NewInt(1), ten10000), ten10000), ten10000)
ten100000 := MulBig(MulBig(MulBig(MulBig(big.NewInt(1), ten30000), ten30000), ten30000), ten10000)
ten300000 := MulBig(MulBig(MulBig(big.NewInt(1), ten100000), ten100000), ten100000)
ten1000000 := MulBig(MulBig(MulBig(MulBig(big.NewInt(1), ten300000), ten300000), ten300000), ten100000)
return &BigNumbers{
Zero: big.NewInt(0),
One: big.NewInt(1),
Two: big.NewInt(2),
Nine: big.NewInt(9),
Ten: ten,
Thousand: thousand,
Million: million,
Ten10: ten10,
Ten30: ten30,
Ten100: ten100,
Ten300: ten300,
Ten1000: ten1000,
Ten3000: ten3000,
Ten10000: ten10000,
Ten30000: ten30000,
Ten100000: ten100000,
Ten300000: ten300000,
Ten1000000: ten1000000,
}
}
func (n *BigNumbers) Repunit(k int) *big.Int {
rep := n.PowTen(k)
return rep.Sub(rep, n.One).Div(rep, n.Nine)
}
func (n *BigNumbers) PowTen(p int) *big.Int {
result := big.NewInt(1)
pow := func(n int, one, three *big.Int) {
for n >= 3 {
result.Mul(result, three)
n -= 3
}
for n >= 1 {
result.Mul(result, one)
n--
}
}
mul := func(n int, one, three *big.Int) int {
mod := n % 10
pow(mod, one, three)
return n / 10
}
p = mul(p, n.Ten, n.Thousand)
p = mul(p, n.Ten10, n.Ten30)
p = mul(p, n.Ten100, n.Ten300)
p = mul(p, n.Ten1000, n.Ten3000)
p = mul(p, n.Ten10000, n.Ten30000)
p = mul(p, n.Ten100000, n.Ten300000)
for p > 0 {
result.Mul(result, n.Ten1000000)
p--
}
return result
}