对于无符号整数值,操作+, - ,*和<<是 计算模2n,其中n是无符号整数的位宽 类型。松散地说,这些无符号整数运算丢弃率很高 溢出后的位,程序可能依赖于'' 。
我尝试测试它,但结果不一致 - http://play.golang.org/p/sJxtSHbigT:
package main
import "fmt"
func main() {
fmt.Println("test")
var num uint32 = 1 << 35
}
这给出错误:
prog.go:7: constant 34359738368 overflows uint32
[process exited with non-zero status]
但根据规范应该没有错误,而是我应该看到0。
答案 0 :(得分:6)
您引用的规范特指&#34;操作+, - ,*和&lt;&lt;&#34;的结果。您正在尝试定义一个常量,而不是查看其中一个操作的结果。
您也无法使用这些超大值来输入这些操作。编译器不会为你包装任何值;这只是那些操作的运行时行为。
package main
import "fmt"
func main() {
var num uint32 = 1 + 1 << 35
fmt.Printf("num = %v\n", num)
}
prog.go:6: constant 34359738369 overflows uint32
[process exited with non-zero status]
这是一个有趣的例子。
var num uint32 = (1 << 31) + (1 << 31)
fmt.Printf("num = %v\n", num)
prog.go:6: constant 4294967296 overflows uint32
[process exited with non-zero status]
在这种情况下,编译器尝试在编译时评估(1 << 31) + (1 << 31)
,产生常量值4294967296
,这个值太大而不适合。
var num uint32 = (1 << 31)
num += (1 << 31)
fmt.Printf("num = %v\n", num)
num = 0
在这种情况下,添加是在运行时执行的,并且值会像您期望的那样包围。
答案 1 :(得分:3)
那是因为1 << 35
是一个无类型的常量表达式(它只涉及数值常量)。在您指定之前,它不会成为uint32
。 Go禁止你为一个变量分配一个常量表达式,这个表达式会溢出它,因为这样的东西几乎肯定是无意的。