Golang中int8左移8位为何会变成负数?
Golang中int8左移8位为何会变成负数? https://play.golang.com/p/TyFQoBR9dQr
package main
import (
"fmt"
)
func main() {
var c int8 = 1 // 00000001
fmt.Println(c << 6) // 01000000 = 64
fmt.Println(c << 7) // 10000000 = -128 ???
}
4 回复
如果最高位以1开头,则为负数;否则为正数。
看起来你可能已经搞清楚了,但关于正在发生的事情的更多信息,请参阅二进制补码 - 维基百科。
在Go语言中,int8是8位有符号整数,其取值范围为-128到127。当对int8进行左移操作时,如果结果超出该范围,会发生溢出,导致符号位被改变,从而得到负数。
具体到你的代码:
c << 6:00000001左移6位得到01000000,即64,仍在int8范围内。c << 7:00000001左移7位得到10000000,在二进制补码表示中,最高位为1表示负数,该值对应-128。
这是因为Go语言中移位操作的结果类型与左操作数相同(这里是int8),当移位导致溢出时,高位被截断,只保留低8位。
示例代码验证:
package main
import (
"fmt"
)
func main() {
var c int8 = 1
fmt.Printf("c << 6 = %d (二进制: %08b)\n", c<<6, uint8(c<<6))
fmt.Printf("c << 7 = %d (二进制: %08b)\n", c<<7, uint8(c<<7))
// 对比使用更大类型的情况
var d int32 = 1
fmt.Printf("d << 7 = %d (二进制: %032b)\n", d<<7, uint32(d<<7))
}
输出:
c << 6 = 64 (二进制: 01000000)
c << 7 = -128 (二进制: 10000000)
d << 7 = 128 (二进制: 00000000000000000000000010000000)
可以看到,使用int32时左移7位得到128,而int8由于类型限制,结果被截断为-128。


