也许我错过了一些东西,但我找不到一个简单的方法来完成这个简单的任务。当我通过“~”运算符对二进制数求反时,由于二进制补码,它返回一个负数:
>>> bin(~0b100010) # this won't return '0b011101'
'-0b100011'
如果我只想将 0 转换为 1,反之亦然,就像在经典的逻辑补码中一样?
也许我错过了一些东西,但我找不到一个简单的方法来完成这个简单的任务。当我通过“~”运算符对二进制数求反时,由于二进制补码,它返回一个负数:
>>> bin(~0b100010) # this won't return '0b011101'
'-0b100011'
如果我只想将 0 转换为 1,反之亦然,就像在经典的逻辑补码中一样?
>>> bin(0b111111 ^ 0b100010)
'0b11101'
>>>
您作为函数的答案:
def complement(n):
size = len(format(n, 'b'))
comp = n ^ ((1 << size) - 1)
return '0b{0:0{1}b}'.format(comp, size)
>>> complement(0b100010)
'0b011101'
我让它保留了原始的位长。int 构造函数不关心前导零:
>>> complement(0b1111111100000000)
'0b0000000011111111'
>> int(complement(0b1111111100000000), 2)
255
超级讨厌:
>>> '0b' + ''.join('10'[int(x)] for x in format(0b100010,'b')).lstrip('0')
'0b11101'
这是另外几个函数,它们返回我得出的数字的补码。
单线:
def complement(c):
return c ^ int('1'*len(format(c, 'b')), 2)
一种更数学的方式:
def complement(c):
n=0
for b in format(c, 'b'): n=n<<1|int(b)^1
return n
此外,使用 functools (例如巴洛克式)对最后一个进行单线化:
def complement(c):
return functools.reduce( lambda x,y: x<<1|y, [ int(b)^1 for b in format(c, 'b') ])
最后,第一个使用 math.log 来计算二进制数字的无用的书呆子变体:
def complement(c):
c ^ int('1' * math.floor(math.log((c|1)<<1, 2)), 2)
另一个功能更像是补充整数的“Hack”。您可以使用相同的逻辑来补充二进制。想知道为什么我没有遇到可以做同样事情的 python 外部库。Python 的下一个版本应该在内置函数中解决这个问题
定义补码(x):
b = bin(x)[2:] c= [] for num in b: if num == '1': c.append('0') elif num == '0': c.append('1') cat = ''.join(c) res = int(cat, 2) return print(res)