我在golang中无法理解1<<s
如果0
,var s uint = 33
如何返回1<<33
。
但是8589934592
返回-16
。
移位运算符转换如何以0值结束。
我正在阅读语言规范,并停留在本节中:
https://golang.org/ref/spec#Operators
特别是来自文档的这一段:
来自Golang官方文档的一些示例:
var s uint = 33
var i = 1<<s // 1 has type int
var j int32 = 1<<s // 1 has type int32; j == 0
var k = uint64(1<<s) // 1 has type uint64; k == 1<<33
更新:
另一个非常相关的问题,例如:
package main
import (
"fmt"
)
func main() {
v := int16(4336)
fmt.Println(int8(v))
}
该程序返回
4336
将
-16
转换为int16
时,数字int8
如何变成ojit_code 最佳答案
如果您有这个:
var s uint = 33
fmt.Println(1 << s)
然后引用的部分适用:
由于
s
不是常数(它是一个变量),因此1 >> s
是非常数移位表达式。左操作数是1
,它是未类型化的常量(例如int(1)
将是类型化的常量),因此如果表达式将只是1
而不是1 << s
,它将被转换为一种类型:fmt.Println(1)
在上面,未类型化的常量
1
将被转换为int
,因为这是其默认类型。常量的默认类型为Spec: Constants:以上结果取决于体系结构。如果
int
为32位,则为0
。如果int
为64位,则为8589934592
(因为将1
位移位33次会将其从32位int
号中移出)。在Go操场上,
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)
上面的输出(在Go Playground上尝试):
int size: 4
0
0
8589934592
如果我在64位计算机上运行上述应用程序,则输出为:
int size: 8
8589934592
0
8589934592
有关常量在Go中的工作方式,另请参见The Go Blog: Constants。
请注意,如果您编写
1 << 33
,那是不一样的,那不是一个非恒定移位表达式,您的引用适用于:“非恒定移位表达式的左操作数”。 1<<33
是一个常数移位表达式,在“恒定空间”中求值,结果将转换为int
,该值不适合32位int
,因此产生了编译时错误。它适用于变量,因为变量可能会溢出。常量不会溢出:参见How does Go perform arithmetic on constants?
更新:
回答您的附加问题:从
int16
转换为int8
只会保留最低的8位。整数使用2's complement格式表示,如果数字为负,则最高位是1
。这在Spec: Conversions:中有详细说明
因此,当您将
int16
值转换为int8
时,如果源编号在位置7(第8位)上具有1
,则结果将为负,即使源不是负数也是如此。同样,如果源在位置7处具有0
,则即使源为负,结果也将为正。请参阅以下示例:
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()
}
输出(在Go Playground上尝试):
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
查看相关问题:
When casting an int64 to uint64, is the sign retained?
Format printing the 64bit integer -1 as hexadecimal deviates between golang and C