2 回答

TA貢獻1810條經驗 獲得超4個贊
如果你有這個:
var?s?uint?=?33 fmt.Println(1?<<?s)
然后引用的部分適用:
如果非常量移位表達式的左操作數是無類型常量,則首先將其隱式轉換為移位表達式單獨由其左操作數替換時所假定的類型。
因為s
不是常量(它是變量),所以1 >> s
是非常量移位表達式。左操作數是1
一個無類型常量(例如int(1)
,將是一個類型化常量),因此它被轉換為一個類型,如果表達式簡單地1
代替1 << s
:
fmt.Println(1)
在上面,無類型常量1
將被轉換為int
,因為這是它的默認類型。常量的默認類型在Spec: Constants:
無類型常量有一個默認類型,即常量在需要類型化值的上下文中隱式轉換為的類型,例如,在沒有顯式類型的短變量聲明中。
i := 0
無類型常量的默認類型分別為bool
、rune
、int
、float64
或complex128
,string
具體取決于它是布爾值、符文、整數、浮點數、復數還是字符串常量。
上述結果取決于體系結構。如果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
請注意,如果您編寫1 << 33
,那是不一樣的,那不是一個非常量移位表達式,您的引用適用于:"the left operand of a non-constant shift expression"。1<<33
是一個常量移位表達式,在“常量空間”進行計算,結果將轉換為int
不適合 32 位的int
,因此會出現編譯時錯誤。它適用于變量,因為變量可能會溢出。常量不會溢出:
數值常量表示任意精度的精確值并且不會溢出。
從 轉換為int16
只int8
保留最低 8 位。整數使用2 的補碼格式表示,其中最高位是1
負數。
這在規范中有詳細說明:轉換:
在整數類型之間轉換時,如果值為有符號整數,則將其符號擴展為隱式無限精度;否則為零擴展。然后將其截斷以適合結果類型的大小。例如,如果
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()
}
輸出(在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
- 2 回答
- 0 關注
- 200 瀏覽
添加回答
舉報