亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 移位運算符轉換

Golang 移位運算符轉換

Go
qq_笑_17 2023-06-12 15:53:41
我不明白在 golang 中如何1<<s返回0if var s uint = 33。而是1<<33回歸8589934592。移位運算符轉換如何以 0 值結束。我正在閱讀語言規范并停留在本節中: https ://golang.org/ref/spec#Operators特別是文檔中的這一段:“移位表達式中的右操作數必須具有無符號整數類型,或者是由 uint 類型的值表示的無類型常量。 如果非常量移位表達式的左操作數是無類型常量,則首先將其隱式轉換為類型它會假設移位表達式是否被單獨的左操作數替換?!惫俜?Golang 文檔中的一些示例:var s uint = 33var i = 1<<s                  // 1 has type intvar j int32 = 1<<s            // 1 has type int32; j == 0var k = uint64(1<<s)          // 1 has type uint64; k == 1<<33更新:另一個非常相關的問題,舉個例子:package mainimport (    "fmt")func main() {v := int16(4336)    fmt.Println(int8(v))}本節目回歸-16數字如何4336轉換-16為int16int8
查看完整描述

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無類型常量的默認類型分別為boolrune、intfloat64complex128,string具體取決于它是布爾值、符文、整數、浮點數、復數還是字符串常量。

上述結果取決于體系結構。如果int是 32 位,它將是0.?如果int是 64 位,它將是8589934592(因為將位移動133 次會將其移出 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,因此會出現編譯時錯誤。它適用于變量,因為變量可能會溢出。常量不會溢出:

數值常量表示任意精度的精確值并且不會溢出。

從 轉換為int16int8保留最低 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


查看完整回答
反對 回復 2023-06-12
?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

您正在以 32 位模式構建和運行程序(去游樂場?)。其中,int 是 32 位寬的,其行為與 int32 相同。



查看完整回答
反對 回復 2023-06-12
  • 2 回答
  • 0 關注
  • 200 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號