使用BigInts创建位掩码

4

有没有更有效率的方法来执行以下计算?它能正常工作,但是我感觉 x &= (1 << 8) - 1 ^ 1 << 3 可以被简化以避免一些计算并提高速度。

def unset_mask(width, index):
    return (1 << width) - 1 ^ 1 << index

x = 0b11111111
x &= unset_mask(8, 3)
assert x == 0b11110111
3个回答

3
实际上,您不需要说明width。当您这样做时,Bigints会表现出正确的方式:
>>> bin(255 & ~(1 << 3))
'0b11110111'
>>> bin(65535 & ~(1 << 3))
'0b1111111111110111'
>>> bin(75557863725914323419135 & ~(1 << 3))
'0b1111111111111111111111111111111111111111111111111111111111111111111111110111'

因为负数在前面有"无限"个1。所以当你对一个正数取反码(它的开头是"无限"个0),你会得到一个负数(确切地说是-(x + 1))。只是不要相信负数的bin表示法;它不能反映内存中实际的位。所以你需要像这样重写unset_mask
def unset_mask(index):
    return ~(1 << index)

x = 0b11111111
x &= unset_mask(3)
print x == 0b11110111  # prints True

非常感谢!那是一个非常详尽的答案和解释。 - Noctis Skytower

1

这将取消该位:

x ^= 1 << 3 & x

在一个函数中:
def unset_bit(x, n):
    return 1 << n & x ^ x

我无法将它缩短到更短的长度。 - Marco de Wit

1

您可以使用此功能来清除 x 中的一些内容:

x &= ~(1 << index)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接