В C я мог бы, например, обнулить бит # 10 в 32-битном беззнаковом значении следующим образом:
unsigned long value = 0xdeadbeef;
value &= ~(1<<10);
Как мне это сделать в Python?






value = 0xdeadbeef
value &= ~(1<<10)
Вы пробовали скопировать и вставить свой код в Python REPL, чтобы посмотреть, что произойдет?
>>> value = 0xdeadbeef
>>> value &= ~(1<<10)
>>> hex (value)
'0xdeadbaef'
Опустите 'unsigned long', точки с запятой также не нужны:
value = 0xDEADBEEF
value &= ~(1<<10)
print value
"0x%08X" % value
В Python есть операторы битовой манипуляции в стиле C, поэтому ваш пример в Python буквально такой же, за исключением ключевых слов типа.
value = 0xdeadbeef
value &= ~(1 << 10)
Побитовые операции с целыми числами Python работают так же, как в C. Операторы &, | и ^ в Python работают так же, как и в C. Оператор ~ работает как для целого числа со знаком в C; то есть ~x вычисляет -x-1.
Вы должны быть осторожны со сдвигом влево, поскольку целые числа Python не имеют фиксированной ширины. Используйте битовые маски, чтобы получить биты младшего разряда. Например, чтобы выполнить эквивалент сдвига 32-битного целого числа, выполните (x << 5) & 0xffffffff.
Если вы собираетесь выполнять много манипуляций с битами (и вы гораздо больше заботитесь о читабельности, а не о производительности для своего приложения), вы можете создать целочисленную оболочку, чтобы включить нарезку, как в 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
Вы также должны проверить BitArray, удобный интерфейс для работы с последовательностями битов.
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)
Некоторые общие битовые операции, которые могут служить примером:
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
Отличное решение! Вы можете подумать о добавлении его как пакета
pip. Однако просто отметим, что он работает только с Python 2. (что имеет смысл, поскольку ему более 10 лет ...)