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 回复

因为 int8 是无符号的——所以最后一位决定了方向

更多关于Golang中int8左移8位为何会变成负数?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


如果最高位以1开头,则为负数;否则为正数。

看起来你可能已经搞清楚了,但关于正在发生的事情的更多信息,请参阅二进制补码 - 维基百科

在Go语言中,int8是8位有符号整数,其取值范围为-128到127。当对int8进行左移操作时,如果结果超出该范围,会发生溢出,导致符号位被改变,从而得到负数。

具体到你的代码:

  • c << 600000001左移6位得到01000000,即64,仍在int8范围内。
  • c << 700000001左移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。

回到顶部