2 回答

TA貢獻2039條經驗 獲得超8個贊
當您必須處理字節級或位級數據時,按位運算符就派上用場了。
在這里,我列出了一些使用位操作和代碼示例的示例(無特定順序):
1.它們很常見,并且是密碼學和散列函數(例如MD5)中許多算法的一部分。
2.如果您想“節省”空間并將多個“bool”變量打包成一個int,它們也經常使用,例如,您為每個 bool 變量分配一個位。您必須使用按位運算符才能單獨更改/讀取位。
例如,將 8 位/布爾值打包為一個int:
flags := 0x00 // All flags are 0
flags |= 0x02 // Turn the 2nd bit to 1 (leaving rest unchanged)
flags |= 0xff // Turn 8 bits (0..7) to 1
flags &= 0xfe // Set the lowest bit to 0 (leaving rest unchanged)
istrue := flags&0x04 != 0 // Test if 3rd bit is 1
3.另一個領域是壓縮數據,您希望充分利用 abyte并使用其所有位來存儲/檢索某些信息(位是計算和數字通信中的基本信息單位)。
4.類似于壓縮但又不完全相同:比特流。它還用于通過不發送完整字節而是發送具有任意位長度的字段來節省數據流中的空間。
我編寫并發布了一個高度優化的位級 Reader 和 Writer 包,在此處開源:github.com/icza/bitio。您將在其源代碼中看到各種位操作的廣泛使用。
5.另一個實際用途:測試(整數)數的某些屬性。知道整數的二進制表示(二進制補碼),在它們的二進制表示中有數字的某些特征。例如,如果最低位為 0,則整數(以 2 的補碼形式)是偶數(可以被 2 整除):
func isEven(i int) bool {
return i&0x01 == 0
}
通過測試整數的位,您還可以判斷它是否是 2 的冪。例如,如果一個正數只包含一位1,那么它就是 2 的冪(例如2 = 0x02 = 00000010b,16 = 0x10 = 00010000但17 = 0x11 = 00010001不是 2 的冪)。
6. 許多編碼/解碼過程也使用位操作。最簡單的是UTF-8 編碼,它使用可變長度編碼將 unicode 代碼點(rune在 Go 中)表示為字節序列。
可變長度編碼的一個簡單變體可能是使用字節的最高位(如果 0 索引是第 8 位或第 7 位)來表示是否需要更多字節來解碼一個數字,而其余 7 位始終是“有用的” “ 數據。您可以測試最高位并“分離” 7 個有用的位,如下所示:
b := readOneByte()
usefulBits := b & 0x7f
hasMoreBytes := b & 0x80 != 0
使用這種變長編碼的好處是,即使你uint64在 Go 中使用內存中 8 個字節的類型,小數字仍然可以用更少的字節表示(范圍內的數字0..127只需要 1 個字節?。?。如果要存儲或傳輸的樣本有很多小值,僅此一項就可以將數據壓縮到 1/8 = 12.5 %。不利的一面是大數字(即使在最高字節中也有位)將使用超過 8 個字節。是否值得取決于樣本的啟發式。
X. 名單還在繼續……
在 Go(以及許多其他編程語言)中,你能不知道/使用按位運算符嗎?答案是肯定的。但如果您了解他們,有時他們可以讓您的生活更輕松,您的程序更有效率。
如果您想了解有關該主題的更多信息,請閱讀維基百科文章:Bitwise operation并谷歌術語“Bitwise Operators Tutorial”,有很多好文章。

TA貢獻1757條經驗 獲得超7個贊
對于他們在技術上所做的事情,請查看這里的評論
package main
import "fmt"
func main() {
// Use bitwise OR | to get the bits that are in 1 OR 2
// 1 = 00000001
// 2 = 00000010
// 1 | 2 = 00000011 = 3
fmt.Println(1 | 2)
// Use bitwise OR | to get the bits that are in 1 OR 5
// 1 = 00000001
// 5 = 00000101
// 1 | 5 = 00000101 = 5
fmt.Println(1 | 5)
// Use bitwise XOR ^ to get the bits that are in 3 OR 6 BUT NOT BOTH
// 3 = 00000011
// 6 = 00000110
// 3 ^ 6 = 00000101 = 5
fmt.Println(3 ^ 6)
// Use bitwise AND & to get the bits that are in 3 AND 6
// 3 = 00000011
// 6 = 00000110
// 3 & 6 = 00000010 = 2
fmt.Println(3 & 6)
// Use bit clear AND NOT &^ to get the bits that are in 3 AND NOT 6 (order matters)
// 3 = 00000011
// 6 = 00000110
// 3 &^ 6 = 00000001 = 1
fmt.Println(3 &^ 6)
}
View it on the playground
請注意,我舉了兩個例子|來表明它并不是真正的加法,如1 + 5.
至于實際用途,我相信其他一些人可以用更多的例子來評論,但一個常見的用途是為許可系統之類的東西創建標志位掩碼。
- 2 回答
- 0 關注
- 175 瀏覽
添加回答
舉報