Go中的位运算

 go教练   2019-08-01 16:17   191 人阅读  0 条评论

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

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

 微信截图_20190801095347.png

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

&操作符

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

 微信截图_20190801095359.png

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

 微信截图_20190801095408.png

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

 微信截图_20190801095419.png

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

 微信截图_20190801095427.png

|操作符

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

 微信截图_20190801095437.png

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

 微信截图_20190801095451.png

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

 微信截图_20190801095502.png

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

使用位作为配置信息

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

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

 微信截图_20190801095533.png

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

^ 操作符

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

 微信截图_20190801095554.png

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

 微信截图_20190801095602.png

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

 微信截图_20190801095612.png

当上述代码执行会输出a and b have same sign? false。使用 Go Playground可以修改不同的符号查看不同的结果。

使用^作为位非操作

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

 微信截图_20190801095620.png

&^ 运算符

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

 微信截图_20190801095632.png

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

 微信截图_20190801095642.png

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

 微信截图_20190801095650.png

<< 和 >>运算符

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

 微信截图_20190801095701.png

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

 微信截图_20190801095711.png

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

 微信截图_20190801095719.png

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

 微信截图_20190801095740.png

或者将一个值乘4:

 微信截图_20190801095748.png

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

 微信截图_20190801095757.png

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

 微信截图_20190801095805.png

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

 微信截图_20190801095814.png

位移运算符注意事项

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

以上就是今天给大家介绍的Go中的位运算,如果你还想了解更多关于学习go语言的知识技巧,可以持续关注我们http://www.fastgolang.com

本文地址:http://fastgolang.com/121.html
版权声明:本文为原创文章,版权归 go教练 所有,欢迎分享本文,转载请保留出处!

 发表评论


表情

还没有留言,还不快点抢沙发?