我无法理解golang如果1<< s返回0如果var s uint = 33。但是1<<< 33返回8589934592。移位运算符转换如何以值0结束。
我正在读这门语言……
您正在以32位模式构建和运行程序(去游乐场?)。在其中,int是32位宽,并且与int32的行为相同。
如果你有这个:
var s uint = 33 fmt.Println(1 << s)
然后引用的部分适用:
如果非常量移位表达式的左操作数是无类型常量,则首先将其隐式转换为如果移位表达式仅由其左操作数替换时将采用的类型。
因为 s 因此,它不是一个常数(它是一个变量) 1 >> s 是一个非常数移位表达式。左操作数是 1 这是一个无类型的常数(例如 int(1) 将是一个类型化的常量),因此它被转换为一种类型,如果表达式是简单的,它将获得 1 代替 1 << s :
s
1 >> s
1
int(1)
1 << s
fmt.Println(1)
在上面,无类型常量 1 将被转换为 int ,因为那是它的默认类型。默认的常量类型是 规格:常数:
int
无类型常量有一个 默认类型 这是在需要输入值的上下文中隐式转换常量的类型,例如,在a中 短变量声明 如 i := 0 没有明确类型的地方。无类型常量的默认类型是 bool , rune , int , float64 , complex128 要么 string 分别取决于它是布尔值,符文,整数,浮点数,复数还是字符串常量。
i := 0
bool
rune
float64
complex128
string
以上结果取决于架构。如果 int 是32位,它将是 0 。如果 int 是64位,它将是 8589934592 (因为转移了一个 1 位33次将使其从32位移位 int 数)。
0
8589934592
在游乐场,大小 int 是32位(4字节)。看这个例子:
fmt.Println("int size:", unsafe.Sizeof(int(0))) var s uint = 33 fmt.Println(1 << s) fmt.Println(int32(1) << s) fmt.Println(int64(1) << s)
以上输出(试试吧 去游乐场 ):
int size: 4 0 0 8589934592
如果我在64位计算机上运行上述应用程序,则输出为:
int size: 8 8589934592 0 8589934592
另见 Go Blog:常数 关于常量如何在Go中工作。
请注意,如果你写 1 << 33 ,这不是相同的,这不是一个非常量的移位表达式,您的引用适用于: “非常量移位表达式的左操作数” 。 1<<33 是一个常量移位表达式,在“常量空间”处计算,结果将转换为 int 它不适合32位 int 因此编译时错误。它适用于变量,因为变量可能会溢出。常量不会溢出:
1 << 33
1<<33
数字常量表示任意精度的精确值,不会溢出。
看到 Go如何对常量执行算术运算?
的 更新: 强>
回答你的补充:转换自 int16 至 int8 只保留最低的8位。并使用整数来表示整数 2的补充 格式,最高位是 1 如果数字是负数。
int16
int8
这是详细的 规格:转换:
在整数类型之间进行转换时,如果该值是有符号整数,则将其符号扩展为隐式无限精度;否则它是零扩展。 的 然后将其截断以适合结果类型的大小。 强> 例如,如果 v := uint16(0x10F0) , 然后 uint32(int8(v)) == 0xFFFFFFF0 。转换始终产生有效值;没有溢出的迹象。
v := uint16(0x10F0)
uint32(int8(v)) == 0xFFFFFFF0
所以当你转换一个 int16 价值 int8 ,如果源编号有 1 在位位置7(第8位),结果将为负,即使源不是负的。同样,如果来源有 0 在位7位,即使源为负,结果也是正的。
看这个例子:
for _, v := range []int16{4336, -129, 8079} { fmt.Printf("Source : %v\n", v) fmt.Printf("Source hex: %4x\n", uint16(v)) fmt.Printf("Result hex: %4x\n", uint8(int8(v))) fmt.Printf("Result : %4v\n", uint8(int8(v))) fmt.Println() }
输出(试试吧 去游乐场 ):
Source : 4336 Source hex: 10f0 Result hex: f0 Result : -16 Source : -129 Source hex: ff7f Result hex: 7f Result : 127 Source : 8079 Source hex: 1f8f Result hex: 8f Result : -113
查看相关问题:
将int64转换为uint64时,符号是否保留?
格式化打印64位整数-1作为十六进制在golang和C之间偏离