如何修改整数中的位?

问题描述 投票:0回答:5

我有一个值为

7
(
0b00000111
) 的整数,我想将其替换为
13
(
0b00001101
) 的函数。替换整数中的位的最佳算法是什么?

例如:

set_bits(somevalue, 3, 1) # What makes the 3rd bit to 1 in somevalue?
python binary bit
5个回答
71
投票

这些适用于任何大小的整数,甚至大于 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'

51
投票

您只需要:

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 是最低有效位。

另请注意,新值是返回,无法像您所示的那样“就地”修改整数(至少我不这么认为)。


11
投票

您可以使用按位运算。 http://wiki.python.org/moin/BitwiseOperators

如果要将给定位设置为 1,可以在给定位置上使用按位“或”与 1:

0b00000111 | 0b00001000 = 0b00001111

要将给定位设置为 0,您可以使用按位“and”

0b00001111 & 0b11111011 = 0b00001011

请注意,0b 前缀表示二进制数,0x 表示十六进制数。


0
投票

根据提供的示例,听起来您正在寻找交换整数中的位。 例如,在 7

(0b00000111)
中,如果交换第 3 个和第 1 个位置中的位,您将获得 13
(0b00001101)

我将以下内容作为函数签名

swap_bits(val, i, j)

最好的算法是什么?那么,下面的算法需要常数时间,O(1)。

def swap_bits(val, i, j):
    """
    Given an integer val, swap bits in positions i and j if they differ
    by flipping their values, i.e, select the bits to flip with a mask.
    Since v ^ 1 = 0 when v = 1 and 1 when v = 0, perform the flip using an XOR.
    """
    if not (val >> i) & 1 == (val >> j) & 1:
        mask = (1 << i) | (1 << j)
        val ^= mask
    return val

示例:

 >>> swap_bits(7, 3, 1)
 13

代码利用了一些技巧,这是 Sean Anderson 的“好资源”。我正在努力提供 Python 代码片段here


0
投票

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 # Set the bit indicated by the mask to True. v ^= (not x) * mask # If x is True, do nothing (XOR with 0). If x is False, use the mask for clearing the bit indicated by the mask (XOR with 1 in the requested position). return v # Return the result, we're done. >>> set_bit(7, 3, 1) 15 >>> set_bit(set_bit(7, 1, 0), 3, 1) 13

请注意,位数(索引)从 0 开始,其中 0 是最低有效位。

© www.soinside.com 2019 - 2024. All rights reserved.