我有一个值为7
(0b00000111
)的整数,现在想要用一个函数将其替换成13
(0b00001101
)。请问在一个整数中替换位的最佳算法是什么?
例如:
set_bits(somevalue, 3, 1) # What makes the 3rd bit to 1 in somevalue?
这些方法适用于任何大小的整数,甚至大于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'
你只需要:
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是最低有效位。
还要注意,新值是被返回的,没有办法像您展示的那样就地修改整数(至少我认为不行)。
v
可以是一个numpy数组,而index
可以是标量或与v
长度相同的numpy数组。非常有用!谁知道设置位需要如此聪明。 - John Lunzerdef set_bit(v, index, x)
实现方案吗? - Kos您可以使用位运算符。
http://wiki.python.org/moin/BitwiseOperators如果您想将给定的位设置为1,可以在给定位置上使用按位“或”运算符与1:
0b00000111 | 0b00001000 = 0b00001111
如果您想将给定的位设置为0,则可以使用按位“与”运算符:
0b00001111 & 0b11111011 = 0b00001011
请注意,0b前缀表示二进制数,0x前缀表示十六进制数。
根据提供的示例,看起来您想要交换整数中的位。
例如,在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 代码片段。
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
0x
是 十六进制 数字的前缀。你需要的前缀是0b
。 - Some programmer dude