为了账号安全,请及时绑定邮箱和手机立即绑定

无符号整数溢出

无符号整数溢出

Go
aluckdog 2021-07-28 13:05:26
去规范说无符号整数溢出:对于无符号整数值,运算 +、-、* 和 << 是以 2n 为模计算的,其中 n 是无符号整数类型的位宽。粗略地说,这些无符号整数运算会在溢出时丢弃高位,并且程序可能依赖于 ''wrap around''。我尝试对其进行测试,但得到的结果不一致 - http://play.golang.org/p/sJxtSHbigT:package mainimport "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。
查看完整描述

2 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

您引用的规范特指“操作 +、-、* 和 <<”的结果。您正在尝试定义一个常量,而不是查看其中一个操作的结果。


您也不能将那些过大的值用于这些操作的输入。编译器不会为您包装任何值;这只是这些操作的运行时行为。


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,生成常量 value ,该值太大而无法容纳。


var num uint32 = (1 << 31)

num += (1 << 31)

fmt.Printf("num = %v\n", num)

num = 0

在这种情况下,加法是在运行时执行的,并且值会按照您的预期回绕。


查看完整回答
反对 回复 2021-08-02
  • 2 回答
  • 0 关注
  • 297 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信