Skip to content

Commit

Permalink
Added factorial / factorialBig
Browse files Browse the repository at this point in the history
  • Loading branch information
OneOfOne committed Sep 12, 2014
1 parent 47b7e95 commit e80a2aa
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
60 changes: 60 additions & 0 deletions math/fact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package math

import "math/big"

var cache = []uint64{
1, // 0
1, // 1
2, // 2
6, // 3
24, // 4
120, // 5
720, // 6
5040, // 7
40320, // 8
362880, // 9
3628800, // 10
39916800, // 11
479001600, // 12
6227020800, // 13
87178291200, // 14
1307674368000, // 15
20922789888000, // 16
355687428096000, // 17
6402373705728000, // 18
121645100408832000, // 19
2432902008176640000, // 20
}

// Factorial returns the factorial n!, if n > 20 it returns 0, use FactorialBig instead
func Factorial(n uint) uint64 {
if n < uint(len(cache)) {
return cache[n]
}
return 0
}

var (
one = big.NewInt(1)
twenty = big.NewInt(20)
)

func FactorialBig(n uint64) (r *big.Int) {
//fmt.Println("n = ", n)
bn := new(big.Int).SetUint64(n)
r = big.NewInt(1)

if bn.Cmp(one) <= 0 {
return
}

if bn.Cmp(twenty) <= 0 {
return r.SetUint64(Factorial(uint(n)))
}

for i := big.NewInt(2); i.Cmp(bn) <= 0; i.Add(i, one) {
r.Mul(r, i)
}

return
}
18 changes: 18 additions & 0 deletions math/fact_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package math

import "testing"

const fact100 = "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"

func TestFactorialBig20(t *testing.T) {
if FactorialBig(20).Uint64() != Factorial(20) {
t.Errorf("FactorialBig(20) != Factorial(20)")
}
}

func TestFactorialBig100(t *testing.T) {
f100 := FactorialBig(100)
if f100.String() != fact100 {
t.Errorf("Factorial(100) returned %q, expected %q.", f100, fact100)
}
}

0 comments on commit e80a2aa

Please sign in to comment.