Как изменить биты в целое число?

У меня есть целое число со значением 7 (0b00000111), и я хотел бы заменить его на функцию 13 (0b00001101). Какой лучший алгоритм для замены битов в целом числе?

Например:

set_bits(somevalue, 3, 1) # What makes the 3rd bit to 1 in somevalue?

Ответ 1

Вам просто нужно:

def set_bit(v, index, x):
  """Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new value."""
  mask = 1 << index   # Compute mask, an integer with just bit 'index' set.
  v &= ~mask          # Clear the bit indicated by the mask (if x is False)
  if x:
    v |= mask         # If x was True, set the bit indicated by the mask.
  return v            # Return the result, we're done.

>>> set_bit(7, 3, 1)
15
>>> set_bit(set_bit(7, 1, 0), 3, 1)
13

Обратите внимание, что номера бит (index) равны 0, а 0 - младший значащий бит.

Также обратите внимание, что возвращается новое значение, нет способа изменить целое число "на месте", как вы показываете (по крайней мере, я так не думаю).

Ответ 2

Они работают для целых чисел любого размера, даже более 32 бит:

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

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

Если вам нравятся короткие вещи, вы можете просто использовать:

>>> val = 0b111
>>> val |= (1<<3)
>>> '{:b}'.format(val)
'1111'
>>> val &=~ (1<<1)
'1101'

Ответ 3

Вы можете использовать побитовые операции. http://wiki.python.org/moin/BitwiseOperators

если вы хотите установить данный бит в 1, вы можете использовать побитовое "или" с 1 в заданной позиции:

0b00000111 | 0b00001000= 0b00001111

для установки заданного бита в 0 вы можете использовать поразрядные 'и'

0b00001111 & 0b11111011= 0b00001011

Обратите внимание, что префикс 0b для двоичных чисел, а 0x - для шестнадцатеричного.