在刷题和完成实验室给的作业中,有关位操作的问题还是挺多的,所以在这里再写一遍加深学习记忆233
位操作是基于二进制进行运算的,所以本文所有描述均基于二进制
一,基础操作符:
"&"(与):同1则1
eg:0000 0010 & 0000 0011 = 0000 0010 (2&3=2)
"|"(或):同0则0
eg:0000 0010 | 0000 0011 = 0000 0011 (2|3=3)
"^"(异或):相同为0,相异为1
eg:0000 0010 ^ 0000 0011 = 0000 0001 (2^3=1)
"~"(取反):0变1,1变0 <六个操作符中唯一一个单目操作符>
eg: ~ 0000 0010 = 1111 1101 (~2=-3)
"<<"(左移):全部左移若干位,高位舍去,低位补0 <左移一位相当于乘2>
eg:0000 1111 << 1 = 0001 1110(15<<1=30)
">>"(右移):全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样
****位操作的对象是整型数****
****位操作的运算优先级较低,所以最好使用括号****
二,位操作常用小技巧:
1>.判断奇偶:
对二进制数来说,奇偶的区别在于最末一位是0还是1:
1 for i in range (100): 2 if i&1 ==0: 3 print ("%d是偶数"%i) 4 else: 5 print ("%d是奇数"%i)
这里还有个常用小技巧--判断某数是否为2的幂(Leetcode231):
设该数为n,如果n 位与(n-1)的结果为0,则为2的幂
2>.交换两个数:
使用位操作交换两个数的方便之处是不需要使用第三方变量,但是位操作只能交换整型数据:
1 def swap(a,b): #a=0000 0011,b=0000 0100,第一步:a=a^b=0000 0111; 2 if a!=b: #第二步:b=b^a=0000 0100^0000 0111=0000 0011(此时b=a) 3 a^=b #解释:b=b^a => b=b^(a^b)因为异或运算满足交换律,所以,b^(a^b)=b^b^a, 4 b^=a #一个数与其自身异或的结果为0,而0异或任何数都不变,所以此时b=a 5 a^=b #第三步:a=a^b=0000 0111^0000 0011=0000 0100(此时a=b) 6 print(a,b) #解释:a=a^b => a=a^b^a=b(同第二步原理) 7 8 a,b=3,4 9 swap(a,b)
3>.变换符号
只需要对该数取反加一:
1 def function(num): 2 return ~num+1 3 n=5 4 print (function(n))
4>.求绝对值
先判断该数的正负性,若为正数则直接返回,若为负数就改变符号
而判断是否为负,可以通过二进制数右移31位直接判断符号,0为正,1为负:
1 def function(num): 2 num>>31 3 if num==0: 4 return num 5 else : 6 return (~num+1) 7 print (function(-5))
对于任何数,与0异或都不变,所以与-1即0xFFFFFFFF异或就相当于取反。所以,a与a右移后的数(i)异或后再减i(因为i为0或-1,所以减i的结果
要么加0要么加1 )也可以得到绝对值,进行优化:
1 def function(num): 2 i=num>>31 3 return (num^i)-i 4 print (function(-5))
以上就是关于位操作简单技巧的介绍,刷题过程中遇到我会继续补充。
位操作还可以解决八皇后问题~还有其他的趣味应用~遇到的话再一一补充。