Go 中的位运算

首发于:https://studygolang.com/articles/12291

在以前内存和处理能力(CPU)都是非常昂贵的,于是直接在位上编程就成为了处理信息的首选方式(在有些情况下也是唯一的方式)。如今,直接对位进行操作在底层系统、图像处理和密码学等领域还是至关重要的。

在 Go 语言中支持以下几种操作位的方式:

接下来我们会对每一个操作符进行详细的讨论并给出一些可以应用位操作的实例。

操作符

在 Go 中, 操作符用来在两个整数之间进行位 AND 运算。AND 操作有以下特性:

AND 操作符是一个很好的将整数的指定位清零的方式。在下面的例子中,我们使用 运算符将数字后 4 位清零。

所有的二进制操作符都支持简写形式,我们可以把上面的例子改为简写形式:

另外一个小技巧就是可以通过 来判断一个数字是奇数还是偶数。我们可以将数字和值 1 使用 做 AND 运算。如果结果是 1,那说明原来的数字是一个奇数。

在线运行

操作符

用来做数字的位 OR 运算。OR 操作符有以下特性:

我们可以使用这个特性来将一个整数中的指定位置为 1。在下面的例子里,我们使用 OR 运算将第 3、7、8 位置为 1。

在线运行

当对一个数字使用掩码技术,OR 是非常有用的。下面的例子我们可以设置更多的位:

在线运行

在上面的例子中,我们不仅有数字 196 中的所有位,而且最后的两位也被数字 3 置 1。我们可以一直进行置 1 操作,直到所有的位都为 1。

使用位作为配置信息

现在,回顾 。我们可以使用这个技巧来查询指定位上的值。例如 将会返回 ,因为在 中 的所有位都被置 1 了。所以我们能够使用 OR 和 AND 来设置和读取配置信息的值。

下面的代码完成了这个功能。函数 转换给定的字符串。它接收两个参数:第一个参数 是一个要被转换的字符串,第二个参数 使用掩码指定转换时的配置信息。

在线运行

调用 将会把字符串转换成小写,反转并将每个单词的首字母转换成大写。当 上的第 2、3、4 位为 1 时(conf 等于 14)将会执行上述操作。在内部我们使用 if 语句来取出这些位并且根据相应的配置操作字符串。

操作符

XOR 操作符在 Go 中用 表示。XOR 是特例化的 OR,它有以下特性:

这就暗示了我们可以使用 XOR 来切换指定位上的值。例如,给定一个 16 位的值,我们可以使用下面的代码来切换它的前八位:

在之前的代码中,位的值通过 XOR 操作在 0 和 1 之间切换。XOR 的一个实际的用途就是比较两个数字正负号是否相同。两个数字 、,如果 那么 a 和 b 同号,如果 那么 a 和 b 异号。

在线运行

当上述代码执行会输出 。使用 Go Playground 可以修改不同的符号查看不同的结果。

使用 作为位非操作

不像其它语言(C/C++、Java、Python、Javascript 等),Go 没有一元运算符。XOR 操作符 可以作为一元操作符来计算一个数字的补码。给定一个位 ,在 Go 中 将会反转 x 的位。我们可以通过 来计算变量 的补码。

在线运行

运算符

运算符叫做 AND NOT。它是一个 使用 后,再使用 操作的简写。该操作符定义如下:

它有一个有意思的特性:如果第二个操作符返回 1。那么该位将会被清 0。

下面这个代码片段使用 AND NOT 操作符来清掉 的后 4 位( 到 )。

在线运行

和 运算符

和其它 C 家族语言一样,Go 使用 和 来代表左移或者右移运算,定义如下:

例如:在下面的片段中, 使用左移运算符()左移 3 次。每次的结果都会被打印出来。

需要注意的是,每次左移右边的位都会被 0 填充。相反的,使用右移运算符时左边的位都会被 0 填充(有符号数字除外,具体请看之后的Arithmetic Shifts章节)。

一些简单的左移和右移的使用技巧就是乘法和除法,其中每次的位移都是乘或者除 2 次幂。下面的代码将 200 除以 2。

在线运行

或者将一个值乘 4:

在线运行

位移运算符提供一种非常有趣的方式来设置一个二进制的值。我们使用 和 来设置 第三位的值。

在线运行

或者使用 和位移运算符来测试第 n 位是不是指定的值:

在线运行

使用 和位移运算来给第 n 位置 0:

在线运行

位移运算符注意事项

当移动的是一个有符号的值,Go 将会自动的适配位移运算。在向右位移时,正负位上的值将会填充在缺失的位上。

via: https://medium.com/learning-the-go-programming-language/bit-hacking-with-go-e0acee258827

作者:Vladimir Vivien

译者:saberuster

校对:rxcai

本文由 GCTT 原创编译,Go 中文网 荣誉推出

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180613G0IBKT00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券