[英]How do I do a bitwise Not operation in Python?
為了測試使用更多基本構建塊(使用 Nand、Or 和 And,在我的情況下)構建 Xor 操作,我需要能夠執行 Not 操作。 內置not
似乎只與單個位做到這一點。 如果我做:
x = 0b1100
x = not x
我應該得到0b0011
但我只得到0b0
。 我究竟做錯了什么? 或者 Python 只是缺少這個基本功能?
我知道 Python 有一個內置的 Xor 函數,但我一直在使用 Python 來測試我需要構建 Xor 門的 HDL 項目/課程的東西。 我想在 Python 中測試這個,但我不能沒有與 Not 門等效的東西。
在 Python 中使用~
的問題在於它適用於有符號整數。 這也是唯一真正有意義的方法,除非您將自己限制在特定的位數上。 它會工作正常按位數學,但它可以使難以解釋的中間結果。
對於 4 位邏輯,您應該從0b1111
減去
0b1111 - 0b1100 # == 0b0011
對於 8 位邏輯,從0b11111111
等中減去。
一般形式是
def bit_not(n, numbits=8):
return (1 << numbits) - 1 - n
實現此目的的另一種方法是分配這樣的掩碼(應該全為 1):
mask = 0b1111
然后與您的號碼進行異或,如下所示:
number = 0b1100
mask = 0b1111
print(bin(number ^ mask))
您可以參考異或真值表以了解其工作原理。
Python 按位 '~' 運算符反轉整數的所有位,但我們看不到本機結果,因為 Python 中的所有整數都有帶符號表示。
我們可以間接檢查:
>>> a = 65
>>> a ^ ~a
-1
或者一樣:
>>> a + ~a
-1
結果 -1 表示所有位都已設置。 但是前面的減號不允許我們直接檢查這個事實:
>>> bin(-1)
'-0b1'
解決方案很簡單:我們必須使用無符號整數。 第一種方法是導入 'numpy' 或 'ctypes' 模塊,它們都支持無符號整數。 但是 numpy 比 ctypes 更簡單(至少對我而言):
import numpy as np
a = np.uint8(0b1100)
y = ~x
檢查結果:
>>> bin(x)
'0b1100'
>>> bin(y)
'0b11110011'
最后檢查:
>>> x + y
255
8 位整數(字節)的無符號整數“255”與“-1”相同,因為所有位都設置為 1。請確保:
>>> np.uint8(-1)
255
另一個最簡單的解決方案,不太正確,但如果您想包含其他模塊,您可以使用 XOR 操作反轉所有位,其中第二個參數將所有位設置為 1:
a = 0b1100
b = a ^ 0xFF
此操作還將刪除有符號整數的最高有效位,我們可以看到如下結果:
>>> print('{:>08b}'.format(a))
00001100
>>> print('{:>08b}'.format(b))
11110011
最后的解決方案還包含一個操作,因此不是最優的:
>>> b = ~a & 0xFF
>>> print('{:>08b}'.format(b))
11110011
試試這個,它被稱為按位補碼運算符:
~0b1100
二進制字符串可用於保留左 0,因為我們知道:
bin(0b000101) # '0b101'
bin(0b101) # '0b101'
此函數將返回輸入數字的 NOT 的字符串格式
def not_bitwise(n):
'''
n: input string of binary number (positive or negative)
return: binary number (string format)
'''
head, tail = n.split('b')
not_bin = head+'b'+tail.replace('0','a').replace('1','0').replace('a','1')
return not_bin
例子:
In[266]: not_bitwise('0b0001101')
Out[266]: '0b1110010'
In[267]: int(not_bitwise('0b0001101'), 2)
Out[267]: 114
In[268]: not_bitwise('-0b1010101')
Out[268]: '-0b0101010'
In[269]: int(not_bitwise('-0b1010101'), 2)
Out[269]: -42
這里的答案在每個答案中都有很大的亮點,但根據邊緣情況,所有答案都不能很好地擴展。
無需修復 8 位掩碼或要求程序員更改掩碼中有多少位,只需根據通過bit_length()
輸入創建掩碼:
def bit_not(num):
return num ^ ((1 << num.bit_length()) - 1)
John La Rooy 給出的一般形式,可以這樣簡化(python == 2.7 and >=3.1):
def bit_not(n):
return (1 << n.bit_length()) - 1 - n
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.