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