📅  最后修改于: 2023-12-03 15:41:41.723000             🧑  作者: Mango
在程序设计中,经常需要判断一个数的二进制表示中哪些位是设置为1的。本文将介绍如何计算一个数在指定范围内的设置位。
假设有一个数 $num$,它的二进制表示为 $b_0b_1b_2\dots b_{n-1}$,其中 $b_i$ 表示二进制中从右边往左数第 $i$ 位的值($i$ 从0开始),$n$ 表示二进制的位数。现在需要计算 $num$ 在指定范围 $[l, r]$ 内的设置位。
首先,我们需要把二进制数 $num$ 中的第 $l$ 位到第 $r$ 位的数值保留,其余位上都设置为0。可以使用一个长度为 $n$ 的二进制数,将第 $l$ 位到第 $r$ 位上都设置为1,其余位上都设置为0,然后与 $num$ 进行按位与操作。这样就得到了指定范围内的数值。例如,下面的代码可以计算 $num$ 在第 2 位到第 4 位内的数值。
mask = int('1110', 2) # mask的二进制表示为1110
result = num & mask
接着,我们可以把结果向右移动 $l$ 位,使它的二进制表示从右往左数第 $l$ 位变成了第0位,从而方便后续的计算。例如,如果在上面的例子中计算得到的数值为 $1010$,则将其向右移动2位后得到 $10$。
最后,我们可以通过不断地将结果分解为2的幂次和的方式,判断二进制中哪些位是设置为1的。例如,如果得到的结果为 $10$(二进制为 $1010$),它可以表示为 $2^1 + 2^3$ 的和,即第 1 和第 3 位上是设置为1的。
具体实现细节可以参考下面的代码。
def get_set_bits(num: int, l: int, r: int):
# 保留[l:r]范围内的数值
mask = (1 << (r - l + 1)) - 1 # 全1的二进制数
mask <<= l # 左移l位
result = num & mask
# 右移l位
result >>= l
# 计算设置位
set_bits = []
bit_pos = 0
while result > 0:
if result & 1 == 1:
set_bits.append(l + bit_pos)
result >>= 1
bit_pos += 1
return set_bits
代码中的 get_set_bits
函数接受三个参数:num
表示要计算的数,l
和 r
表示要计算的范围。函数返回一个列表,其中存放了[l, r]范围内的设置位。例如,如果要计算数值 38
在第 2 位到第 4 位内的设置位,可以调用这个函数:
>>> get_set_bits(38, 2, 4)
[2, 4]
这个结果表明数值 38
的二进制表示中,第 2 和第 4 位上是设置为1的。