Python中的“bitswise Not”中断了2的补全符

2024-04-18 19:42:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要在Python中执行“~”操作,但不考虑2的补码。我通过使用XOR实现了这一点,您知道另一种方法吗?(效率更高)

a = 0b101
b = 0b10101

print bin(a ^ (2 ** a.bit_length() - 1)) #0b10
print bin(b ^ (2 ** b.bit_length() - 1)) #0b1010

Tags: 方法binbitlength效率printxor补码
2条回答

另一种方式,尽管有些人(包括我自己)可能会质疑它更好,那就是:

from string import maketrans
tbl = maketrans("01","10")

int(bin(42)[2:].translate(tbl),2)

第一个位只是设置一个转换表来反转字符串中的10位。在

第二个位获得二进制表示(42->;0b101010),去掉前面的{},并通过转换来反转这些位。然后您只需使用int(,2)将该二进制字符串转换回数字。在


如果您可以将其限制为特定的宽度,而不是使用数字本身的宽度,那么问题很简单(以32位为例):

^{pr2}$

这就是~已经在做的事情了。棘手的部分是Python有无限长的整数,所以当你反转一个数字时,它至少在概念上被符号扩展为无限个1,这意味着你得到的是负数。在

>>> bin(~0b101)
'-0b110'
>>> bin(~0b10101)
'-0b10110'

要将这些数字转换为无符号数字,您需要决定您关心的位数。也许你用的是8位字节。然后你可以用一个字节的1位值来计算它们:

^{pr2}$

或者,如果您想匹配输入数字的精确位长度,您的解决方案是合理的。为了提高效率,你可以切换指数左移。用~和{}代替{},可能会更清楚。在

>>> bin(~a & ((1 << a.bit_length()) - 1))
'0b10'
>>> bin(~b & ((1 << b.bit_length()) - 1))
'0b1010'

(我怀疑像& 0xFFFF这样的硬编码掩码在实践中是正确的解决方案。对于基于bit_length()的答案,我想不出一个好的真实世界用例。)

相关问题 更多 >