This program runs fine one my machine (go1.2.1 linux/amd64):
package main
import "fmt"
const bigint = 1<<62
func main() {
fmt.Println(bigint)
}
But with the go playground, it gives overflow error - http://play.golang.org/p/lAUwLwOIVR
It seem that my build is configured with 64 bits for integer constans, playground configured with 32 bits.
But spec say that implementation must give at least 256 bits of precision for constants?
Also see code in my other question -- the scanner standard package has code:
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
Since space is 32, this don't work on 32-bit playground at all.
How can this be?
Constants itself are not limited in precision but when used in code they are converted to a suitable type. From the spec:
A constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment or as an operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type. For instance, 3.0 can be given any integer or any floating-point type, while 2147483648.0 (equal to 1<<31) can be given the types float32, float64, or uint32 but not int32 or string.
So if you have
const a = 1 << 33
fmt.Println(a)
you will get an overflow error as the default type for integer constants int
can't hold the value 1 << 33
on 32 bit environments. If you convert the constant to int64
everything's fine on all platforms:
const a = 1 << 33
fmt.Println(int64(a))
The constant GoWhitespace
is not directly used in the scanner.
The Whitespace attribute used in the Scanner
type is of type uint64
and GoWhitespace
is assigned to it:
s.Whitespace = GoWhitespace
This means you deal with a uint64
value and 1 << ' '
(aka. 1 << 32
) is perfectly valid.
Example (on play):
const w = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
c := ' '
// fmt.Println(w & (1 << uint(c))) // fails with overflow error
fmt.Println(uint64(w) & (1 << uint(c))) // works as expected
As stated by nemo, you can give a type to your constant. Just specify int64
and it works fine :)
http://play.golang.org/p/yw2vsvMigk
package main
import "fmt"
const bigint int64 = 1<<62
func main() {
fmt.Println(bigint)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With