簡體   English   中英

如何在 Python 中進行按位 Not 操作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM