[SOLVED]How to deal with big numbers?

I’m struggling in getting my func returning a big number.

The problem I’m trying to resolve is this Euler problem

package main

import (
	"fmt"
	"math"
)

var result float64 = 0

func recursive(a float64) float64 {

	if a == 1000 {
		return math.Pow(a, a)
	}
	result := math.Pow(a, a) + recursive(a+1)

	return result
}

func main() {
	number := recursive(1)
	fmt.Printf("%f \n", math.Mod(number, 10))
	fmt.Println(number)
	fmt.Printf("%T", number)
}

If you try to run the file you will realize that the number returns an +Inf as a result.
I also tried another version to use the Big package

But seems not to work

var result = big.NewFloat(0)

func recursive(a float64) *big.Float {

	if a == 1000 {
		return big.NewFloat(math.Pow(a, a))
	}
	result := result.Add(big.NewFloat(math.Pow(a, a)), recursive(a+1))

	return result
}

func main() {
	number := recursive(1)
	fmt.Println(number)
	fmt.Printf("%T", number)
}

Any idea how to work on this? The language should enable us to work with big numbers for big operations. That’s how computers are supposed to make our life easier isn’t?

Thank you all beforehand.

This still requires a float to be able to hold the result of a to the power of a, which may not be the case. You should probably stick to the math.Big operations completely.

1 Like

Hi @calmh

Thank you for the quickly response

I’ve followed your advice in base my operations within math/big and I’m almost there !
Right now I’ve got my mega “float” like the following

	fmt.Printf("%v\n", number)//2.1408741971581619e+304
	fmt.Printf("%.0f\n", number) //21408741971581618636221029630219066086671271169079483757669418360887732284499609424176930917131077628985575094390147067241010104955965388726304719693474240813764442335935458626051882071796360073774738583428374768817298348847668019161813275455543235266722346695176308044050838027572556754443589426824085504

(Being number a *big.Float) Is there any way of getting the last digits? I did not found a way to get % to work in here, moreover I’ve tried to convert my *big.float into an integer but I want all decimals to become integers. Any suggestions on this?

This is the snippet so far

import (
	"fmt"
	"math/big"
)

var result = big.NewFloat(0)

func recursive(a int) *big.Float {

	var bigA *big.Float = big.NewFloat(float64(a))

	if a == 1000 {
		return bigA.SetMantExp(bigA, a)
	}
	result := result.Add(bigA.SetMantExp(bigA, a), recursive(a+1))

	return result
}

func main() {
	number := recursive(1)
	fmt.Printf("%.0f\n", number)
}

Which last digits do you mean? Both of your first two prints show a 305 digit number, so I guess it’s accurate?

Hi Marcos,
you don’t need big numbers for tis problem.
Here is my solution for this problem:

package main

import (
    "fmt"
    "strconv"
)

const k = 10000000000

func modPower(n int) int {
    var res = 1
    for i:=1; i <= n; i++ {
        res = (res * n) % k
    }
    return res
}

func main() {
    var euler = 0
    for j := 1; j<= 1000; j++ {
        euler = (euler + modPower(j)) % k
    }
    fmt.Println(strconv.Itoa(euler))
}

I meant to get the last digits of my var number.
I did not realize we have a Text method under *big.Float
So finally I could manage to get the last 10 digits like this

	number_to_string := number.Text('f', 0)
	last_ten_digits  := number_to_string[len(number_to_string)-10:]

:slight_smile:

If we are only interested in the sum $1^1 + … + n^n $ we of course need the package big. A possible tail recursive solution for this case:

package main
import (
   "fmt"
   "math/big"
)

func sumOfPowers(n int64,res *big.Int) *big.Int {
   if n == 0 {
      return res
   } else {
        nBig := big.NewInt(n)
        return sumOfPowers(n-1, res.Add(res, new(big.Int).Exp(nBig, nBig, nil)))
   }
}

func main() {
   var n int64
   n = 1000
   res := big.NewInt(0)
   fmt.Println(sumOfPowers(n,res))
}

Just for interest: In Haskell the solution would be solved for n=1000 by

sum [ n^n | n <- [1..1000]]
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.