用于提高运算速度,规避算术运算符。
在位操作运算中,不应该试图考虑先得到一个数的二进制码,而应该将这个数看作是一个二进制码,二进制补码与整数之间是一一对应的。诚然 Python语言中有内置函数 bin将一个整数转换为二进制,Python中使用该函数转换为负数并不是其补码。因此不能先得到该数的二进制码。同时绞尽脑汁得到一个数的二进制补码是没有必要的。
&:按位与操作,只有 1 &1 为1,其他情况为0。可用于进位运算。
|:按位或操作,只有 0|0为0,其他情况为1。
~:逐位取反。
^:异或,相同为0,相异为1。可用于加操作(不包括进位项)。
<<:左移操作,2的幂相关
>>:右移操作,2的幂相关
判断一个整数的二进制补码中 1 的个数:
既然一个整数在计算机内部为二进制的补码,那么直接对整数进行位操作即可,没有必要进行进制的转换。
1)将整数通过移位并与1进行与操作,即可判断当时末尾是否为1.但是由于整数以二进制补码的方式存储,正数右移与负数右移得到的效果并不相同,负数在右移过程中会自动补 1 .由于在c 或c++这种语言中数据的类型要先声明,如 int为32位,而在python中,由于动态语言的特性,数据的位数理想上是不受限制的,因此可通过 移位的次数进行判断,int型数据移位不能超过32即可,这样程序的循环次数恒定为32.
1 class Solution:
2 def NumberOf1(self, n):
3 # write code here
4 m = 0
5 result = 0
6
7 while m < 32:
8 if n & 1:
9 result += 1
10 n = n >> 1
11 m += 1
12 return result
2):同样的,可以通过左移 1 再与输入值进行与操作进行判断。仍然是由于Python不会存在溢出现象,因此需要用到 数据类型的位数,进行限制。
1 class Solution():
2 def getResult(self, n):
3 m = 1
4 result = 0
5 i = 0
6
7 while i < 32:
8 i += 1
9 if m&n :
10 result += 1
11 m = m << 1
12 return result
3)一个二进制减一再于自身与操作能够将最后一位1置零。如 1011-1 = 1010 1010&1011 = 1010、1010-1 = 1001 1001 & 1010 = 1000、1000-1 = 0111 0111 &1000 = 0000
但是,Python不会溢出,因此负数在进行持续减一 的运算,若通过当前值是否为0进行循环终止条件会导致死循环。因此需要为正负数分别设定终止条件。
1 class Solution2():
2 def getResult(self, n):
3 result = 0
4 if n >= 0:
5 while n:
6 result += 1
7 n = (n - 1)&n
8 else:
9 while n >= -2147483648:
10 result += 1
11 n = (n - 1)&n
12 return result
4):一个负数必然对应一个正数,先通过加法运算得到负数的相反数,这样可以将负数当作正数进行操作,唯一不同的是,负数的符号位要多一个 1
1 # -*- coding:utf-8 -*-
2 class Solution:
3 def NumberOf1(self, n):
4 # write code here
5 result = 0
6
7 if n < 0:
8 n = n + (1<<31)
9 result += 1
10 result += bin(n)[2:].count('1')
11 return result
5):结合方法 4 与 3之前的方法:
1 # -*- coding:utf-8 -*-
2 class Solution:
3 def NumberOf1(self, n):
4 # write code here
5 result = 0
6
7 if n < 0:
8 n = n + (1<<31)
9 result += 1
10 while n:
11 result += 1
12 n = n&(n-1)
13 return result