我如何在Python中进行按位操作?

Lau*_*ren 21 python

为了测试使用更多基本构建块构建Xor操作(在我的例子中使用Nand,Or和And),我需要能够执行Not操作.内置not似乎只用单位做这个.如果我做:

x = 0b1100
x = not x
Run Code Online (Sandbox Code Playgroud)

我应该得到,0b0011但我得到了0b0.我究竟做错了什么?或者Python只是缺少这个基本功能?

我知道Python有一个内置的Xor函数,但我一直在使用Python来测试HDL项目/课程的内容,我需要构建一个Xor门.我想用Python测试这个,但我不能没有相当于Not门.

Joh*_*ooy 26

~在Python中使用的问题在于它适用于有符号整数.这也是唯一真正有意义的方法,除非你将自己限制在特定的位数.它可以通过按位数学运行,但是它可能很难解释中间结果.

对于4位逻辑,您应该从中减去 0b1111

0b1111 - 0b1100  # == 0b0011
Run Code Online (Sandbox Code Playgroud)

对于8位逻辑,从中减去0b11111111等.

一般形式是

def bit_not(n, numbits=8):
    return (1 << numbits) - 1 - n
Run Code Online (Sandbox Code Playgroud)


An0*_*0ne 10

Python 按位运算~符反转整数的所有位,但我们看不到本机结果,因为 Python 中的所有整数都有符号表示。

我们可以间接地检查:

>>> a = 65
>>> a ^ ~a
-1
Run Code Online (Sandbox Code Playgroud)

或者相同:

>>> a + ~a
-1
Run Code Online (Sandbox Code Playgroud)

结果 -1 表示所有位均已设置。但前面的减号不允许我们直接检查这个事实:

>>> bin(-1)
'-0b1'
Run Code Online (Sandbox Code Playgroud)

解决方案很简单:我们必须使用无符号整数。第一种方法是导入numpyctypes均支持无符号整数的模块。但 numpy 比 ctypes 使用更简单(至少对我来说):

import numpy as np
a = np.uint8(0b1100)
y = ~x
Run Code Online (Sandbox Code Playgroud)

检查结果:

>>> bin(x)
'0b1100'
>>> bin(y)
'0b11110011'
Run Code Online (Sandbox Code Playgroud)

最后检查:

>>> x + y
255
Run Code Online (Sandbox Code Playgroud)

8 位整数(字节)的无符号整数“255”与“-1”含义相同,因为所有位均设置为 1。请确保:

>>> np.uint8(-1)
255
Run Code Online (Sandbox Code Playgroud)

还有另一个最简单的解决方案,不太正确,但如果您想包含其他模块,您可以使用 XOR 运算反转所有位,其中第二个参数将所有位设置为 1:

a = 0b1100
b = a ^ 0xFF
Run Code Online (Sandbox Code Playgroud)

此操作还将删除有符号整数的最高有效位,我们可以看到如下结果:

>>> print('{:>08b}'.format(a))
00001100
>>> print('{:>08b}'.format(b))
11110011
Run Code Online (Sandbox Code Playgroud)

最后,解决方案还包含一项操作,因此不是最佳的:

>>> b = ~a & 0xFF
>>> print('{:>08b}'.format(b))
11110011
Run Code Online (Sandbox Code Playgroud)


小智 8

实现此目的的另一种方法是分配这样的掩码(应该全为 1):

mask = 0b1111
Run Code Online (Sandbox Code Playgroud)

然后与您的号码进行异或,如下所示:

number = 0b1100
mask = 0b1111
print(bin(number ^ mask))
Run Code Online (Sandbox Code Playgroud)

您可以参考异或真值表以了解其工作原理。