2015-02-10 120 views
16

最近我读到golang规范而面临着一些有趣的运营商:某些运算符“|”,“^”,“&”,“&^”之间的区别。 Golang

& bitwise AND   integers 
| bitwise OR    integers 
^ bitwise XOR   integers 
&^ bit clear (AND NOT) integers 

我试着用它玩,但我已经明白了只有一个就是“|”添加整数和“+”运算符另外可以使用浮点数,字符串等。

它们在实践中用于什么?任何人都可以对上述4个操作员进行解释吗?

+2

拿起一本像Petzold的“代码”一样的书来获得对二进制表示和计算基础的基本理解。 – 2015-02-10 17:22:04

回答

30

当您必须使用字节或比特级数据时,按位运算符将发挥作用。

这里我列出使用位操作的代码样本的例子屈指可数(排名不分先后):


他们是常见的,在密码散列算法很多一部分功能(例如MD5)。

2.他们,如果你想“节省”空间和你包多个“布尔”变量成一个int例如,分配一个位给每个布尔变量也经常使用。您必须使用按位运算符才能够单独更改/读取位。

例如包装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 

的另一个领域是压缩要获得最大的一个byte和使用其所有位数据存储/读取一些信息(有一点是计算和数字通信中的基本信息单元)。

4.与压缩类似但不完全相同:比特流。它也用于通过不发送完整字节而是具有任意位长度的字段来节省数据流中的空间。

我已经编写并发布了一个高度优化的位级读写器包,在此处打开源码:github.com/icza/bitio。您将会在其来源中看到广泛使用各种位操作。

5.另一实际用法:测试(整数)数字的某些属性。知道整数的二进制表示(Two's complement),它们的二进制表示中存在数字的某些特征。例如一个整数(2的补数)是甚至(可以除以2),如果最低位为0:

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 encoding,它使用可变长度编码来表示unicode代码点(Go中的rune)作为字节序列。
可变长度编码的一个简单变化可以是使用字节的最高位(如果是0索引,则为第8或第7)来表示是否需要更多字节来解码数字,其余7位始终是“有用”的数据。可以测试的最高位和“分离”的7个有用比特这样的:

b := readOneByte() 
usefulBits := b & 0x7f 
hasMoreBytes := b & 0x80 != 0 

使用这样的可变长度编码的利润是,即使你在Go是在存储器的8个字节使用uint64类型,小数字仍然可以使用较少的字节表示(0..127范围内的数字只需要1个字节!)。如果要存储或传输的样本具有许多较小的值,则这可以将数据压缩到1/8 = 12.5%。缺点是大数字(即使在最高字节中也有位)将使用多于8个字节。是否值得这取决于样本的启发式。

X.而这样的例子不胜枚举...


你可以住在不知道/使用位运算符在Go(和许多其他的编程语言)?答案是肯定的。但如果你了解他们,有时他们可以让你的生活更轻松,并且你的节目更有效率。

如果您想了解更多关于这个主题的内容,请阅读维基百科文章:Bitwise operation和谷歌术语“位运算符教程”,这里有很多很好的文章。

+0

谢谢!真的很好的答案。你能否提出这本书,解释像我这样的新手“低级”编程的一些基础知识? (没有深入到太技术和数学术语) – 2015-02-11 07:49:33

+1

@TimurFayzrakhmanov只是谷歌它(术语_“按位运算符教程”_),在互联网上有很多很好的教程。大部分都是语言特定的,但或多或​​少都适用于所有的编程语言。这是一个很好的搜索结果,用1分钟的搜索结果找到:[了解位运算符](http://code.tutsplus.com/articles/understanding-bitwise-operators--active-11301)。另请阅读维基百科文章:[按位操作](http://en.wikipedia.org/wiki/Bitwise_operation) – icza 2015-02-11 08:55:10

+0

明白了!再次感谢!) – 2015-02-11 09:42:09

13

对于他们技术上来说在这个

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

至于实际用途,我敢肯定其他一些人可以用更多的例子评论,但一个常见的用途是创建一个像权限系统的标志位掩码。

相关问题