这个程序在我的机器上运行正常(go1.2.1 linux / amd64):
package main
import "fmt"
const bigint = 1<<62
func main() {
fmt.Println(bigint)
}
但是在go操场上,它会出现溢出错误 - http://play.golang.org/p/lAUwLwOIVR
似乎我的构建配置为64位用于整数常量,操场配置为32位。
但是spec say实现必须为常量提供至少256位的精度?
另请参阅my other question中的代码 - 扫描仪标准软件包包含代码:
const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
由于空间为32,所以根本不能在32位游乐场上工作。
这怎么可能?
答案 0 :(得分:4)
常量本身不受精度限制,但在代码中使用时,它们会转换为合适的类型。 来自spec:
常量可以通过常量声明或转换显式给定,或者在变量声明或赋值中使用时隐式赋值,或者作为表达式中的操作数使用。如果是常量值不能表示为相应类型的值。例如,3.0可以给出任何整数或任何浮点类型,而2147483648.0(等于1 <&lt; 31)可以给出float32,float64或uint32类型但不能给出int32或string。
所以,如果你有
const a = 1 << 33
fmt.Println(a)
您将get an overflow error作为整数常量int
的默认类型,无法在32 bit environments上保留值1 << 33
。如果你将常量转换为int64
所有平台上的一切都很好:
const a = 1 << 33
fmt.Println(int64(a))
常量GoWhitespace
不会直接在扫描仪中使用。
Scanner
类型中使用的Whitespace attribute类型为uint64
和GoWhitespace
is assigned to it:
s.Whitespace = GoWhitespace
这意味着您处理uint64
值,而1 << ' '
(又名。1 << 32
)完全有效。
示例(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
答案 1 :(得分:1)
如nemo所述,你可以给你的常数一个类型。只需指定int64
即可正常使用:)
http://play.golang.org/p/yw2vsvMigk
package main
import "fmt"
const bigint int64 = 1<<62
func main() {
fmt.Println(bigint)
}