mirror of
https://github.com/golang/go
synced 2024-11-19 13:54:56 -07:00
math/big: faster Int.Binomial(n, k) for k > n/2
benchmark old ns/op new ns/op delta BenchmarkBinomial 478664 4410 -99.08% Fixes #10084. Change-Id: Ib75034428e32c79c9a660ae9f9bd396afc6a7f11 Reviewed-on: https://go-review.googlesource.com/8351 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
3ed9e4ca3c
commit
919a6fbeab
@ -184,6 +184,10 @@ func (z *Int) MulRange(a, b int64) *Int {
|
||||
|
||||
// Binomial sets z to the binomial coefficient of (n, k) and returns z.
|
||||
func (z *Int) Binomial(n, k int64) *Int {
|
||||
// reduce the number of multiplications by reducing k
|
||||
if n/2 < k && k <= n {
|
||||
k = n - k // Binomial(n, k) == Binomial(n, n-k)
|
||||
}
|
||||
var a, b Int
|
||||
a.MulRange(n-k+1, n)
|
||||
b.MulRange(1, k)
|
||||
|
@ -219,6 +219,45 @@ func TestMulRangeZ(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBinomial(t *testing.T) {
|
||||
var z Int
|
||||
for _, test := range []struct {
|
||||
n, k int64
|
||||
want string
|
||||
}{
|
||||
{0, 0, "1"},
|
||||
{0, 1, "0"},
|
||||
{1, 0, "1"},
|
||||
{1, 1, "1"},
|
||||
{1, 10, "0"},
|
||||
{4, 0, "1"},
|
||||
{4, 1, "4"},
|
||||
{4, 2, "6"},
|
||||
{4, 3, "4"},
|
||||
{4, 4, "1"},
|
||||
{10, 1, "10"},
|
||||
{10, 9, "10"},
|
||||
{10, 5, "252"},
|
||||
{11, 5, "462"},
|
||||
{11, 6, "462"},
|
||||
{100, 10, "17310309456440"},
|
||||
{100, 90, "17310309456440"},
|
||||
{1000, 10, "263409560461970212832400"},
|
||||
{1000, 990, "263409560461970212832400"},
|
||||
} {
|
||||
if got := z.Binomial(test.n, test.k).String(); got != test.want {
|
||||
t.Errorf("Binomial(%d, %d) = %s; want %s", test.n, test.k, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBinomial(b *testing.B) {
|
||||
var z Int
|
||||
for i := b.N - 1; i >= 0; i-- {
|
||||
z.Binomial(1000, 990)
|
||||
}
|
||||
}
|
||||
|
||||
// Examples from the Go Language Spec, section "Arithmetic operators"
|
||||
var divisionSignsTests = []struct {
|
||||
x, y int64
|
||||
|
Loading…
Reference in New Issue
Block a user