博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你必须知道的简单的位操作技巧
阅读量:6581 次
发布时间:2019-06-24

本文共 2250 字,大约阅读时间需要 7 分钟。

【这里我们将讨论一些位操作技巧,如果使用得当会有助于提高你编出的程序执行速度】

 

我们编程或多或少会使用到位操作,位操作是编程中处理整型数据高效方法。例如,想要求出一个整数二进制位中值为 1 的个数,简单的方法是用一个循环,其实我们用一两个位操作的小技巧就能高效的解决。

 

假设读者已经知道整型数据二进制补码表示方式和位操作的基本方式。

我列出下文中将要使用的位操作标记:

&   -  bitwise and|   -  bitwise or^   -  bitwise xor~   -  bitwise not<<  -  bitwise shift left>>  -  bitwise shift right

本文中使用的数字是8bit无符号整型,二进制补码表示,用‘x’标记,结果用‘y’表示。数‘x’的每一比特位标记为b7, b6, b5, b4, b3, b3, b2, b1 和 b0。b7 是符号位,权重最大,b0 权重最小。

 

我们从最简单的开始逐渐过渡到难的。

 

技巧1:检查整数是奇数还是偶数

if ((x & 1) == 0){    // x is even}else{    // x is odd}

相信很多人都知道这个方法,只要整数的最后一位比特是 1 ,那它就是奇数,反之就是偶数。即 b0 位要么是 1 要么是 0 ,‘x’和 1 与(&)运算,保留了最 b0 位,如果 b0 是 1 ,‘x’是奇数,如果 b0 位是 0 ,‘x’是偶数。

如果还不是很清楚我们去一个整数,例如43,二进制表示为00101011,注意 b0 位为 1,我们将 43 与 1 做 & 运算:

1    001010112&   00000001   (note: 1 is the same as 00000001)3    --------4    00000001

从中看到 & 运算怎样擦除了高位的 b7 ~ b1 位的数据只保留了 b0 位,结果为 1,因此知道 43 是奇数。

 

技巧2:测试第n位比特

if (x & (1<

前面讨论过了第一位比特测试,这里做了一些改进,可以测试第任意位比特,只要将与运算的1向左平移相应的位数即可。假设向左平移n位,接下来的与运算就是只保留第n位,其它位都清零了。

下面是简单的演示:

1         00000001    (same as 1<<0)1<<1      000000101<<2      000001001<<3      000010001<<4      000100001<<5      001000001<<6      010000001<<7      10000000

小例子:

122的第三位比特是1吗?(从0开始数)可以这样做:

122 & (1<<3)

122的二进制表示是01111010,(1<<3)即1向左平移3比特00001000。

1    011110102&   000010003    --------4    00001000

我们看到结果不为0,这题的答案是1。

 

技巧3:将第n位设为1

y = x | (1<

和前面的技巧一样,只是把与运算(&)换成了或运算(|)。与1进行或运算将参与运算的位置为1,与0进行或运算参与预算的位不变。

看一个例子:

假设我们要将120的第2位比特设为1:

1    01111000    (120 in binary)2|   00000100    (1<<2)3    --------4    01111100

 

技巧4:将第n位设为0

y = x & ~(1<

这个方法的关键就是~(1<<n),它将第n位设为0,其它位全部为1。看下面:

~1        11111110  (same as ~(1<<0))~(1<<1)   11111101~(1<<2)   11111011~(1<<3)   11110111~(1<<4)   11101111~(1<<5)   11011111~(1<<6)   10111111~(1<<7)   01111111

与‘x’与运算的结果是清零了第n位,不管这一位是1还是0,其它位保持不变。

小例子,将127的第4位设为0:

1    01111111    (127 in binary)2&   11101111    (~(1<<4))3    --------4    01101111

 

技巧5:将第n位取反

y = x ^ (1<

这次使用的是异或运算,如果异或运算的两个操作数相同,运算结果是0,两个操作数不同,结果是1。怎样将第n位取反呢?如果第n位比特为1,将它与1进行异或运算结果就是0,如果它是0,那么它与1异或运算的结果就是1。于是这一位就取反了。

小例子,假设要将值01110101的第5位取反:

1    011101012^   001000003    --------4    01010101

同样的数,第5位是0结果如下:

1    010101012^   001000003    --------4    01110101

注意到没?对一个数进行两次同样的异或运算后结果还是原来的数,这个漂亮的特性可以用在许多编程问题中。

转载于:https://www.cnblogs.com/programnote/p/4686330.html

你可能感兴趣的文章
ffserver联合ffmpeg建立媒体服务器
查看>>
下载稻草人下来刷新+gallery
查看>>
删除浏览器浏览器删除cookie方法
查看>>
微软URLRewriter.dll的url重写的简单使用(实现伪静态)
查看>>
leetcode -- Combination Sum II
查看>>
1z0-052 q209_7
查看>>
PIN码计算锦集
查看>>
[Unity3D]再次点击以退出程序
查看>>
架构师的97种习惯
查看>>
PHP 开发 APP 接口 学习笔记与总结 - XML 方式封装通信接口
查看>>
对一道编程题的后续思考
查看>>
IT基础架构规划方案之实际网络设计案例
查看>>
Navicat for MySQL 使用SSH方式链接远程数据库(二)
查看>>
poj 1274The Perfect Stall
查看>>
ibm BIP2276E: The flow includes a message flow of node type 'ComIbmFileReadNode'
查看>>
HDU 4720 Naive and Silly Muggles (外切圆心)
查看>>
垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
查看>>
Ubuntu上运行Blender,在控制台上查看运行结果
查看>>
怎么检查网站的死链接呢?
查看>>
scrapy爬虫框架实例一,爬取自己博客
查看>>