今天来讲讲二进制与位运算!
二进制相信大家都知道,就是只有0和1,逢2进1。
那么位运算又是什么呢?
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
首先来认识一下位运算的符号:
& (与) ,| (或) , ~ (取反符) ,^ (按位异或)
>>(二进制右移) , <<(二进制左移)
含义 | Pascal语言 | C语言 |
按位与 | a and b | a & b |
a or b | a | b | |
按位异或 | a xor b | a ^ b |
按位取反 | not a | ~a |
按位左移 | a shl b | a << b |
无符号右移 | a shr b | a >> b |
那么各个符号的作用又如何呢?
首先设A=11011,B=10110
1. &
即当两个数所表示二进制某位上的数都是1时,结果为1,否则为0。
A&B=10010
2.|
当两个数所表示的二进制中,在相同位上,如果有一个数是1,则结果为1,否则为0.
A|B=11111
3.~
把某个数的每一位上的数都取反,即0变成1,1变成0.
~A=00100(100)
4.^
比较两个数每一位上的数字,如果相同,则结果为0,否则为1。
A^B=01101(1101)
5. >>
把二进制数向右移x位。
A>>1=1101,A>>2=110。
B>>1=1011,B>>2=101.
6.<<
把二进制数向左移x位。
A<<1=110110
不作过多解释。
既然知道了符号效果,那么就可以有简单的应用!
(以下摘自百度百科,对照表见顶部)
去掉最后一位 x shr 1
在最后加一个0 x shl 1
在最后加一个1 x shl 1+1
把最后一位变成1 x or 1
把最后一位变成0 x or 1-1
最后一位取反 x xor 1
把右数第k位变成1 x or (1 shl (k-1))
把右数第k位变成0 x and not (1 shl (k-1))
右数第k位取反 x xor (1 shl (k-1))
取末三位 x and 7
取末k位 x and (1 shl k-1)
取右数第k位 x shr (k-1) and 1
把末k位变成1 x or (1 shl k-1)
末k位取反 | (101001->100110,k=4) | x xor (1 shl k-1)
把右边连续的1变成0 | (100101111->100100000) | x and (x+1)
把右起第一个0变成1 | (100101111->100111111) | x or (x+1)
把右边连续的0变成1 | (11011000->11011111) | x or (x-1)
取右边连续的1 | (100101111->1111) | (x xor (x+1)) shr 1
去掉右起第一个1的左边 | (100101000->1000) | x and (x xor (x-1))(或 x and (-x))
此外还有很多组合的用法,譬如在110100中取出最后的100,就可以这样:
设110100为A,则A&(~(A-1))和~(A-1)&A以及-A&A均为答案。
未完待续(也许吧)