python位运算

Python-位操作( &、 | 、^、~ 、>>、 <<)

 

用于提高运算速度,规避算术运算符。

在位操作运算中,不应该试图考虑先得到一个数的二进制码,而应该将这个数看作是一个二进制码,二进制补码与整数之间是一一对应的。诚然 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
复制代码
posted @ 2021-12-21 23:42  physique  阅读(847)  评论(0编辑  收藏  举报