3 回答

TA貢獻1946條經(jīng)驗 獲得超4個贊
在 Go 中,使用math/big包。
例如,
// OEIS: A000142: Factorial numbers: n! = 1*2*3*4*...*n.
// https://oeis.org/A000045
package main
import (
"fmt"
"math/big"
)
func factorial(x *big.Int) *big.Int {
n := big.NewInt(1)
if x.Cmp(big.NewInt(0)) == 0 {
return n
}
return n.Mul(x, factorial(n.Sub(x, n)))
}
func main() {
fmt.Println(factorial(big.NewInt(5000)))
}
游樂場: https: //play.golang.org/p/53TmmygltkR

TA貢獻1813條經(jīng)驗 獲得超2個贊
func factorial(n int64) *big.Int {
fac := new(big.Int)
fac.MulRange(1, n)
return fac
}
來自 math/big 的 z.MulRange(a, b) 計算從所有 int64 a 到 int64 b 的乘積。它使用拆分和遞歸算法(分而治之)。它比學校階乘算法快得多。計算 1 000 000!很快 = ~ 8.26393168833e+5565708

TA貢獻1789條經(jīng)驗 獲得超10個贊
你需要使用math/big包。您可以實現(xiàn)計算recursively或iteratively. 在大多數(shù)情況下迭代會更快并且產(chǎn)生更少的垃圾。在我的機器上,迭代 impl 的運行速度提高了 3.1 倍,分配的垃圾減少了 2.9 倍。
BenchmarkIterAndRecursive/recursive-6 3000 3891062 ns/op 17181056 B/op 15003 allocs/op
BenchmarkIterAndRecursive/iterative-6 10000 1237597 ns/op 656089 B/op 5172 allocs/op
package main
import (
"fmt"
"log"
"math/big"
"testing"
)
func main() {
fmt.Println(factorial(big.NewInt(5000)))
fmt.Println(factorialIter(5000))
}
func TestIterWorkTheSame(t *testing.T) {
recursive := factorial(big.NewInt(5000))
iterative := factorialIter(5000)
if recursive.Cmp(iterative) != 0 {
log.Fatalf("Invalid computation, \n[%v]\n[%v]", recursive, iterative)
}
}
func BenchmarkIterAndRecursive(b *testing.B) {
b.Run("recursive", func(b2 *testing.B) {
for i := 0; i < b2.N; i++ {
factorial(big.NewInt(5000))
}
})
b.Run("iterative", func(b2 *testing.B) {
for i := 0; i < b2.N; i++ {
factorialIter(5000)
}
})
}
func factorial(x *big.Int) *big.Int {
n := big.NewInt(1)
if x.Cmp(big.NewInt(0)) == 0 {
return n
}
return n.Mul(x, factorial(n.Sub(x, n)))
}
func factorialIter(x int) *big.Int {
result := big.NewInt(1)
for i := 2; i <= x; i++ {
result.Mul(result, big.NewInt(int64(i)))
}
return result
}
- 3 回答
- 0 關注
- 186 瀏覽
添加回答
舉報