如何在Go中获得5000的阶乘

如何在Go中获得5000的阶乘,go,Go,我想计算Go中5000的阶乘,但结果为0,因为结果大于uint64。 但是,我可以在Node.js中使用 const BigNumber = require('big-number'). 围棋中是否有一个等价物 我所做的是: func RecursiveFactorial(number int) big.Int { if number >= 1 { return big.Int{(number) * RecursiveFactorial(number-1)

我想计算Go中5000的阶乘,但结果为0,因为结果大于uint64。 但是,我可以在Node.js中使用

const BigNumber = require('big-number').
围棋中是否有一个等价物

我所做的是:

func RecursiveFactorial(number int) big.Int {
    if number >= 1 {
        return big.Int{(number) * RecursiveFactorial(number-1)
    } else {
        return 1
    }
}

在围棋中,使用
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)))
}
操场:

您需要使用软件包。您可以递归地或迭代地实现计算。在大多数情况下,迭代会更快,产生更少的垃圾。在我的机器上,迭代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
主程序包
进口(
“fmt”
“日志”
“数学/大”
“测试”
)
func main(){
fmt.Println(阶乘(大新特(5000)))
fmt.Println(因子分解器(5000))
}
func TestIterWorkTheSame(t*testing.t){
递归:=阶乘(big.NewInt(5000))
迭代:=因子分解器(5000)
如果递归.Cmp(迭代)!=0{
log.Fatalf(“无效计算,\n[%v]\n[%v]”,递归,迭代)
}
}
func基准测试和递归(b*testing.b){
b、 运行(“递归”,func(b2*testing.b){
对于i:=0;iz、 math/big的MulRange(a,b)计算从所有int64 a到int64 b的乘积。它使用拆分和递归算法(divide and Conquer)。它比学校的阶乘算法快得多。计算1000000!快速=~8.26393168833e+5565708

正如你所知,使用递归计算阶乘是对堆栈的浪费。一个简单的
for
循环就足够了。如果你想练习递归,有更好的例子。@AntonofBTW,不需要使用
大数字
Node.js中的包,它现在内置了
BigInt
支持:
const RecursiveFactorial=n=>n>=1n?n*RecursiveFactorial(n-1n):1n;
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
}
func factorial(n int64) *big.Int {
    fac := new(big.Int)
    fac.MulRange(1, n)
    return fac
}