简体   繁体   中英

100 factorial in golang

I want to calculate 100 factorial in golang. Here's the code I'm using.

var fact big.Int
fact.MulRange(1, 100)

Printing output gives

30414093201713378043612608166064768844377641568960512000000000000

But googling 100! gives 9.332622e+157 . I figured this is probably because of the datatype I am using (or maybe not). How do I solve it? Thanks in advance.

Edit: So I ran this code in go playground and it gave the correct answer. Is this due to a limitation on my PC? Plus when I convert it to string and iterate through it, it shows different numbers

str := fact.String()
for _,val := range str{
    fmt.Print(val)
}

Here is all the code

package main

import (
    "fmt"
    "math/big"
)

func main() {
    var fact big.Int
    fact.MulRange(1, 100)
    fmt.Println(fact)
    n := fact.String()
    fmt.Println(n) //printing 100!
    sum := 0
    for _, i := range n {
        sum += int(i) //sum of each digits in 100!
    }
    fmt.Println(sum)
}

and here is what go env shows:

set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\user\AppData\Local\go-build
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\user\go
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\user\AppData\Local\Temp\go-build839268890=/tmp/go-build -gno-record-gcc-switches

and go version : go version go1.10.1 windows/amd64

To print a string value, simply pass it as-is to fmt.Println() :

str := fact.String()
fmt.Println(str)

Also note that you don't need to call its String() method, the fmt package will do that for you. But not if you just pass fact to it, because Int.String() has pointer receiver, so you have to pass a pointer to it:

fmt.Println(&fact)

Or declare and use *big.Int in the first place, and then you can pass fact simply for printing:

var fact = new(big.Int)
fact.MulRange(1, 100)
fmt.Println(fact)

Actually, since all methods of big.Int have pointer receivers, you should always declare and use pointers of big.Int to avoid surprises.

Note:

Your original code does not print what you want because for range on a string ranges over its runes (characters), and rune is an alias for int32 , so the characters of the result will be printed as individual numbers without spaces between them (because you print each with a fmt.Print() call).

For this same reason, to calculate the sum of digits, you have to convert the runes to the numerical value of the digits they represent. For this, you may simply use digit - '0' :

str := fact.String()
sum := 0
for _, val := range str {
    sum += int(val - '0')
}
fmt.Println(sum)

This will print (tr it on the Go Playground ):

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
648

credit source : quora

you can approach it this way

𝑛!=∏𝑛𝑘=1𝑘

ln(𝑎.𝑏)=ln(𝑎)+ln(𝑏)→ln(𝑛!)=ln(∏𝑛𝑘=1𝑘)=∑𝑛𝑘=1(ln𝑛)

So you can calculate the sum of the logs instead of multiplying all the numbers and then 𝑒𝑥𝑝() the result to get 𝑛! .

𝑒ln(𝑛!)=𝑛!

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Hello, playground")
    fact(100)
}
func fact(n float64){
var sum float64
sum = 0
var i float64
for i= 1;i<=n;i++{
    sum = sum+math.Log(i)

}
fmt.Println(math.Exp(sum))

}

https://play.golang.org/p/74LPoIifNZ-

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM