python3: как получить логическое дополнение (отрицание) двоичного числа, например'010' => '101'? - PullRequest
2 голосов
/ 22 августа 2011

Возможно, я что-то упускаю, но я не могу найти простой способ выполнить эту простую задачу.Когда я иду к отрицанию двоичного числа через оператор "~", он возвращает отрицательное число из-за дополнения к двум:

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

А что если я просто хочу переключить 0 в 1 и наоборот,как в классическом логическом дополнении?

Ответы [ 5 ]

3 голосов
/ 23 августа 2011

ВАШ ответ как функция:

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
3 голосов
/ 22 августа 2011
>>> bin(0b111111 ^ 0b100010)
'0b11101'
>>> 
1 голос
/ 23 августа 2011

Ультра противный:

>>> '0b' + ''.join('10'[int(x)] for x in format(0b100010,'b')).lstrip('0')
'0b11101'
0 голосов
/ 10 марта 2014

Еще одна функция, более «хак» для дополнения целого числа. Вы можете использовать ту же логику для дополнения двоичного файла. Интересно, почему я не наткнулся на внешние библиотеки Python, которые могут делать то же самое. Следующая версия Python должна позаботиться об этом во встроенных модулях

def дополнение (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)
0 голосов
/ 24 августа 2011

Вот еще пара функций, которые возвращают дополнение числа, с которым я выступил.

Однострочный:

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)
...