One of the big limitations of simple number data types is the maximum number
they can hold. A 64 bit unsigned long can hold up to the number `$2^{64}-1$`

.
This is a pretty huge number, but if you try to compute the factorial of a
number like `25!`

, it is not enough. The good news is that there are software
libraries that allow us to surpass this limitation. The bad is that the
computations take longer. Depending on how critical something is, we may wish to
avoid costly computations like these. Anyway, that's the challenge I solved
today using the package Big. My solution is
given below.

```
package main
import (
"fmt"
"math/big"
)
/*tail-recursive factorial function*/
func factorial(
n *big.Int,
accumulate *big.Int,
one *big.Int) *big.Int {
// cmp returns -1 if n < 1
// returns 0 if n == 1
// so here I check n <= 1
if n.Cmp(one) < 0 || n.Cmp(one) == 0 {
return accumulate
}
accumulate.Mul(accumulate, n)
n.Sub(n, one)
return factorial(n, accumulate, one)
}
func main() {
var n int64
fmt.Scanf("%d\n", &n)
N := big.NewInt(n)
accumulate := big.NewInt(1)
var one big.Int
one.SetInt64(1)
result := factorial(N, accumulate, &one)
fmt.Printf("%d\n", result)
}
```

As you may have seen, I have to call methods instead of using the normal mathematical operations available. This was the most annoying part basically. The factorial I wrote is tail-recursive. This means it doesn't take as much memory as the naive solution that let the function calls stack.

Thanks for reading!