Golang 由 &0xFF 引發的問題思考

計算機內的存儲都是利用二進制的補碼進行存儲的。

Golang 由 &0xFF 引發的問題思考

位運算符:

& 位運算 AND

| 位運算 OR

^ 位運算 XOR

&^ 位清空 (AND NOT)

<< 左移

>> 右移

原碼反碼補碼這三個概念

原碼:一個整數,按照絕對值大小轉換成的二進制數,稱為原碼。

反碼:將二進制數按位取反,所得的新二進制數稱為原二進制數的反碼。

補碼:反碼加1稱為補碼。

示例:

int 類型的數,值為5,在計算機中表示為:

原碼:00000000 00000000 00000000 00000101

反碼:11111111 11111111 11111111 11111010

補碼:11111111 11111111 11111111 11111011

解釋:

0xFF的二進制表示就是:1111 1111 高24位補0:0000 0000 0000 0000 0000 0000 1111 1111;

byte類型的數字要&0xff再賦值給int類型,其本質原因就是想保持二進制補碼的一致性。

當byte要轉化為int的時候,高的24位必然會補1,這樣,其二進制補碼其實已經不一致了,&0xff可以將高的24位置為0,低8位保持原樣。這樣做的目的就是為了保證二進制數據的一致性。

有人問為什麼上面的式子中b[0]不是8位而是32位,因為當系統檢測到byte可能會轉化成int或者說byte與int類型進行運算的時候,就會將byte的內存空間高位補1(也就是按符號位補位)擴充到32位,再參與運算。

示例:有一個方法對三個數進行encode之後存儲進一個數。然後有一個decode方法能將這三個數從這一個數中還原回來

package main

import "fmt"

func encodeIntoHex(m map[string]int) (int) {

data := 0

data = m["orange"] & 0xff | m["banana"] & 0xff << 8 | m["apple"] & 0xff << 16

return data

}

func decodeIntoInt(i int) (int, int, int) {

orange := i & 0xff

banana := i >> 8 & 0xff

apple := i >> 16 & 0xff

return orange, banana, apple

}

func main() {

fruit := map[string]int {

"orange": 3,

"banana": 4,

"apple": 5,

}

data := encodeIntoHex(fruit)

fmt.Println(data)

o, b, a := decodeIntoInt(data)

fmt.Println(o, b, a)

}

示例補充:有這樣三個數,encode的時候將數按順序,每個數與0xff與,然後在另外一個8bit位置上與另外一個數字或,即可得到結果。在decode的時候可以再按照每一位解析回來即可。

更多內容請關注每日編程,每天進步一點。


分享到:


相關文章: