我需要在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
答案 0 :(得分:4)
~
已经做了什么。棘手的部分是Python具有无限长度的整数,所以当你反转一个数字时,它是符号扩展的 - 至少从概念上讲 - 是无限数量的1。这意味着你会得到负数。
>>> bin(~0b101)
'-0b110'
>>> bin(~0b10101)
'-0b10110'
要将这些转换为无符号数,您需要确定您关心的位数。也许你正在使用8位字节。然后你可以用一个字节值1位来对它们进行AND运算:
>>> bin(~0b101 & 0xFF)
'0b11111010'
>>> bin(~0b10101 & 0xFF)
'0b11101010'
或者如果您想匹配输入数字的确切位长,您的解决方案是合理的。为了提高效率,您可以切换左移的指数。使用~
和&
代替^
可能会更清楚。
>>> bin(~a & ((1 << a.bit_length()) - 1))
'0b10'
>>> bin(~b & ((1 << b.bit_length()) - 1))
'0b1010'
(我怀疑像& 0xFFFF
这样的硬编码掩码在实践中将是正确的解决方案。我无法想到基于bit_length()
的答案的真实世界用例。)< / p>
答案 1 :(得分:0)
另一种方式,虽然有些人(包括我自己)可能会对此有所争议,但是:
from string import maketrans
tbl = maketrans("01","10")
int(bin(42)[2:].translate(tbl),2)
第一位只是设置一个转换表来反转字符串中的1
和0
位。
第二位获得二进制表示(42
- &gt; 0b101010
),剥离前面的0b
,并通过转换反转位。然后,您只需使用int(,2)
将该二进制字符串转换回数字。
如果你可以将它限制在一个特定的宽度而不是使用数字本身的宽度,那么这是一个简单的问题(使用32位的例子):
val = val ^ 0xffff