計算機內的存儲都是利用二進制的補碼進行存儲的。
![Golang 由 &0xFF 引發的問題思考](http://p2.ttnews.xyz/loading.gif)
位運算符:
& 位運算 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的時候可以再按照每一位解析回來即可。
更多內容請關注每日編程,每天進步一點。
閱讀更多 每日編程 的文章