如何修改整数中的位?

Posted

技术标签:

【中文标题】如何修改整数中的位?【英文标题】:How to modify bits in an integer? 【发布时间】:2012-08-23 19:37:35 【问题描述】:

我有一个值为7 (0b00000111) 的整数,我想用13 (0b00001101) 的函数替换它。替换整数中的位的最佳算法是什么?

例如:

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

【问题讨论】:

就像在 C 中一样。wiki.python.org/moin/BitwiseOperators 小心你的字面整数前缀...0x十六进制数字的前缀。你想要的前缀是0b 【参考方案1】:

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

如果您想将给定位设置为 1,您可以在给定位置使用按位“或”和 1:

0b00000111 | 0b00001000 = 0b00001111

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

0b00001111 & 0b11111011 = 0b00001011

注意,0b 前缀是二进制数,0x 是十六进制数。

【讨论】:

您好,与其发布新答案并删除旧答案,不如考虑编辑旧答案。 :-) 这是我的意图,但我在两个选项卡中打开它并从错误的一个选项卡发送:) 但我想按索引设置字节数。 然后(正如@unwind 向您展示的那样)您可以取 0b1 (=1) 并将其向左移动到正确的位置(他的代码中的 1 【参考方案2】:

你只需要:

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

还要注意,新值是返回的,没有办法像你展示的那样“就地”修改整数(至少我不这么认为)。

【讨论】:

他漫不经心地说,好像成千上万没有二进制经验的人多年来不必一步一步地遍历这段代码,以弄清楚它到底在做什么导致它工作如此完美。 @Aerovistae Heh ... 不知道你是不是在开玩笑。我添加了 cmets 以使代码更加清晰。希望这将为所有这些人节省一些工作。 :) 谢谢!我确实是在开玩笑。必须完全重新学习我的二进制操作以了解发生了什么;从大学起就没有碰过它们。 您可能很高兴知道 as is 这也适用于 numpy 数组。 v 可以是 numpy 数组,index 可以是标量,也可以是与v 长度相同的 numpy 数组。很有用!谁知道设置位需要如此聪明。 @SwiftsNamesake 我敢肯定它可以被巧妙地解决,但这很清楚目标是什么。【参考方案3】:

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

【讨论】:

在整数中设置和清除标志真是太棒了!没有库需要:)【参考方案4】:

按照提供的示例,听起来您正在寻找整数中的位交换。 例如在 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 的 good resource。我正在努力在 Python here 中提供代码 sn-ps。

【讨论】:

以上是关于如何修改整数中的位?的主要内容,如果未能解决你的问题,请参考以下文章

这个位排序代码中的位操作是如何工作的?

如何模拟Delphi records中的位域

在没有按位运算的情况下翻转整数中的位

Java中的位运算

16位二进制补码有符号整数信号数据的位平面分解?

深入研究js中的位运算及用法