python3: How to get logical complement (negation) of a binary number, eg. '010' => '101'?

时光总嘲笑我的痴心妄想 提交于 2020-01-04 06:05:40

问题


Maybe I'm missing something but I can't find a straightforward way to accomplish this simple task. When I go to negate a binary number through the "~" operator it returns a negative number due to the two's complement:

>>> bin(~0b100010) # this won't return '0b011101'
'-0b100011'

What about if I just want to switch 0s into 1s and vice-versa, like in classic logical complement?


回答1:


>>> bin(0b111111 ^ 0b100010)
'0b11101'
>>> 



回答2:


YOU's answer as a function:

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'

I made it preserve the bit length of the original. The int constructor doesn't care about the leading zeros:

>>> complement(0b1111111100000000)
'0b0000000011111111'

>> int(complement(0b1111111100000000), 2)
255



回答3:


Ultra nasty:

>>> '0b' + ''.join('10'[int(x)] for x in format(0b100010,'b')).lstrip('0')
'0b11101'



回答4:


Here's another couple of functions that returns the complement of a number I came out with.

A one-liner:

def complement(c):
    return c ^ int('1'*len(format(c, 'b')), 2)

A more mathematical way:

def complement(c):
    n=0
    for b in format(c, 'b'): n=n<<1|int(b)^1
    return n

Moreover, one-linerizing this last one with functools (such baroque):

def complement(c):
    return functools.reduce( lambda x,y: x<<1|y, [ int(b)^1 for b in format(c, 'b') ])

Finally, a uselessly nerdish variant of the first one that uses math.log to count the binary digits:

def complement(c):
    c ^ int('1' * math.floor(math.log((c|1)<<1, 2)), 2)



回答5:


Another function more a 'Hack' for complementing a Integer. You can use the same logic for complementing binary. Wonder why I did not come across python external libs that can do same. The next ver of Python should take care of this in built-ins

def complement(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)


来源:https://stackoverflow.com/questions/7149604/python3-how-to-get-logical-complement-negation-of-a-binary-number-eg-010

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!