0

I am new to Go and currently following A Tour of Go.

I am currently at page Numeric Constants. Down below is a trimmed down version of the code that runs on that page:

package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
    return x * 0.1
}
func main() {
    fmt.Println(needFloat(Big))
    // fmt.Printf("Type of Big %T", Big)
}

this code compiles successfully with the output 1.2676506002282295e+29

The following code however will not compile and give an error:

package main
import "fmt"
const Big = 1 << 100
func needFloat(x float64) float64 {
    return x * 0.1
}
func main() {
    fmt.Println(needFloat(Big))
    fmt.Printf("Type of Big %T", Big)
}

Output: ./prog.go:9:13: constant 1267650600228229401496703205376 overflows int

Why do you think this happened? I hope you will kindly explain.

alpersunter
  • 93
  • 1
  • 7
  • 1
    check out this similar [question](https://stackoverflow.com/questions/39966952/go-print-large-number) – fabem May 03 '20 at 20:39
  • Have a look at https://blog.golang.org/constants which describes constants in Go in detail. – Volker May 04 '20 at 05:50

3 Answers3

2

The constant Big is an untyped constant. An untyped constant can be arbitrarily large and it doesn't have to fit into any predefined type's limits. It is interpreted and truncated in the context it is used.

The function needFloat gets a float64 argument. At this instance Big is converted to a float64 and used that way.

When you use it for Printf, it tries to pass it in as an int because it is not a decimal number (otherwise it would've converted it to float64), and it causes an overflow. Pass it as float64(Big), and it should work.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
0

I guess the reason is that Big gets computed (i.e. casted right before being passed to needFloat, and gets instead computed as a int64 before the Printf. As a proof, the following statement computes correctly:

package main
import "fmt"
const Big = 1 << 100

func main() {
    fmt.Printf("Type of Big %T", float64(Big))
}

Hope this helps.

Alessandro Santini
  • 1,943
  • 13
  • 17
0

The untyped constant n must be converted to a type before it can be assigned to the interface{} parameter in the call to fmt.Println.

fmt.Println(a ...interface{})

When the type can’t be inferred from the context, an untyped constant is converted to a bool, int, float64, complex128, string or rune depending of the format of the constant.

In this case the constant is an integer, but n is larger than the maximum value of an int.

However, n can be represented as a float64.

const n = 9876543210 * 9876543210
fmt.Println(float64(n))

For exact representation of big numbers, the math/big package implements arbitrary-precision arithmetic. It supports signed integers, rational numbers and floating-point numbers.

This is taken from https://yourbasic.org/golang/gotcha-constant-overflows-int/.

codedge
  • 4,754
  • 2
  • 22
  • 38