Два дополнения в Python - PullRequest
       83

Два дополнения в Python

55 голосов
/ 22 октября 2009

Существует ли в python встроенная функция, которая преобразует двоичную строку, например '111111111111', в целое число дополнения до двух -1?

Ответы [ 14 ]

0 голосов
/ 01 августа 2016

Это намного проще, чем все это ...

для X на N битах: Comp = (-X) & (2 ** N - 1)

def twoComplement(number, nBits):
    return (-number) & (2**nBits - 1)
0 голосов
/ 29 июня 2016

Это работает для 3 байтов. Живой код здесь

def twos_compliment(byte_arr):
   a = byte_arr[0]; b = byte_arr[1]; c = byte_arr[2]
   out = ((a<<16)&0xff0000) | ((b<<8)&0xff00) | (c&0xff)
   neg = (a & (1<<7) != 0)  # first bit of a is the "signed bit." if it's a 1, then the value is negative
   if neg: out -= (1 << 24)
   print(hex(a), hex(b), hex(c), neg, out)
   return out


twos_compliment([0x00, 0x00, 0x01])
>>> 1

twos_compliment([0xff,0xff,0xff])
>>> -1

twos_compliment([0b00010010, 0b11010110, 0b10000111])
>>> 1234567

twos_compliment([0b11101101, 0b00101001, 0b01111001])
>>> -1234567

twos_compliment([0b01110100, 0b11001011, 0b10110001])
>>> 7654321

twos_compliment([0b10001011, 0b00110100, 0b01001111])
>>> -7654321
0 голосов
/ 28 августа 2015

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

def s12(value):
    return -(value & 0b100000000000) | (value & 0b011111111111)

Первая побитовая операция - и используется для расширения знака отрицательных чисел (старший значащий бит установлен), в то время как вторая используется для захвата оставшихся 11 битов. Это работает, поскольку целые числа в Python рассматриваются как значения дополнения до произвольной точности 2.

Затем вы можете объединить это с функцией int, чтобы преобразовать строку двоичных цифр в целое число без знака, а затем интерпретировать ее как 12-разрядное значение со знаком.

>>> s12(int('111111111111', 2))
-1
>>> s12(int('011111111111', 2))
2047
>>> s12(int('100000000000', 2))
-2048

Одним приятным свойством этой функции является то, что она идемпотентна, поэтому значение уже подписанного значения не изменится.

>>> s12(-1)
-1
0 голосов
/ 13 марта 2015

Я использую Python 3.4.0

В Python 3 у нас есть некоторые проблемы с преобразованием типов данных.

Итак ... здесь я расскажу совет для тех (как я), которые много работают с шестнадцатеричными строками.

Я возьму шестнадцатеричные данные и дополню их:

a = b'acad0109'

compl = int(a,16)-pow(2,32)

result=hex(compl)
print(result)
print(int(result,16))
print(bin(int(result,16)))

результат = -1397948151 или -0x5352fef7 или '-0b1010011010100101111111011110111'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...