在命令行和游乐场中进行整数溢出设置

时间:2014-03-16 16:42:31

标签: go

这个程序在我的机器上运行正常(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位游乐场上工作。

这怎么可能?

2 个答案:

答案 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类型为uint64GoWhitespace 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)
}