Как я могу манипулировать битами в Python? - PullRequest
32 голосов
/ 29 сентября 2008

В C я могу, например, обнулить бит # 10 в 32-битном значении без знака, например:

unsigned long value = 0xdeadbeef;
value &= ~(1<<10);

Как мне это сделать в Python?

Ответы [ 9 ]

48 голосов
/ 29 сентября 2008

Битовые операции над Python-интентами работают так же, как в C. Операторы &, | и ^ в Python работают так же, как в C. Оператор ~ работает так же, как целое число со знаком в C; то есть ~x вычисляет -x-1.

Вы должны быть осторожны с левыми сдвигами, поскольку целые числа Python не имеют фиксированной ширины. Используйте битовые маски для получения младших битов. Например, чтобы сделать эквивалент сдвига 32-разрядного целого числа, выполните (x << 5) & 0xffffffff.

11 голосов
/ 29 сентября 2008
value = 0xdeadbeef
value &= ~(1<<10)
4 голосов
/ 20 апреля 2018

Некоторые общие битовые операции, которые могут служить примером:

def get_bit(value, n):
    return ((value >> n & 1) != 0)

def set_bit(value, n):
    return value | (1 << n)

def clear_bit(value, n):
    return value & ~(1 << n)

Использование, например.

>>> get_bit(5, 2)
True
>>> get_bit(5, 1)
False
>>> set_bit(5, 1)
7
>>> clear_bit(5, 2)
1 
>>> clear_bit(7, 2)
3
4 голосов
/ 30 сентября 2008

Вы также должны проверить BitArray , который является хорошим интерфейсом для работы с последовательностями битов.

3 голосов
/ 29 сентября 2008

Python имеет операторы битовых манипуляций в стиле C, поэтому ваш пример в Python такой же, за исключением ключевых слов типа.

value = 0xdeadbeef
value &= ~(1 << 10)
3 голосов
/ 29 сентября 2008

Опустите 'unsigned long', и точки с запятой также не нужны:

value = 0xDEADBEEF
value &= ~(1<<10)
print value
"0x%08X" % value
3 голосов
/ 29 сентября 2008

Вы пытались скопировать и вставить свой код в Python REPL, чтобы увидеть, что произойдет?

>>> value = 0xdeadbeef
>>> value &= ~(1<<10)
>>> hex (value)
'0xdeadbaef'
0 голосов
/ 08 августа 2017
a = int('00001111', 2)
b = int('11110000', 2)
bin(a & b)[2:].zfill(8)
bin(a | b)[2:].zfill(8)
bin(a << 2)[2:].zfill(8)
bin(a >> 2)[2:].zfill(8)
bin(a ^ b)[2:].zfill(8)
int(bin(a | b)[2:].zfill(8), 2)
0 голосов
/ 30 сентября 2008

Если вы собираетесь выполнять много битовых манипуляций (и вы гораздо больше заботитесь о удобочитаемости, а не о производительности своего приложения), то вы можете создать целочисленную оболочку для включения нарезки, как в Verilog или VHDL:

 import math
 class BitVector:
     def __init__(self,val):
         self._val = val

     def __setslice__(self,highIndx,lowIndx,newVal):
         assert math.ceil(math.log(newVal)/math.log(2)) <= (highIndx-lowIndx+1)

         # clear out bit slice
         clean_mask = (2**(highIndx+1)-1)^(2**(lowIndx)-1)

         self._val = self._val ^ (self._val & clean_mask)
         # set new value
         self._val = self._val | (newVal<<lowIndx)

     def __getslice__(self,highIndx,lowIndx):
         return (self._val>>lowIndx)&(2L**(highIndx-lowIndx+1)-1)

 b = BitVector(0)
 b[3:0]   = 0xD
 b[7:4]   = 0xE
 b[11:8]  = 0xA
 b[15:12] = 0xD

 for i in xrange(0,16,4):
     print '%X'%b[i+3:i]

Выходы:

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