【问题标题】:Python How to get set bitPython如何设置位
【发布时间】:2015-08-16 20:13:42
【问题描述】:

假设我有一个在内存中看起来像这样的数字(或类似的,我不知道 Python 是如何存储数字的):

0000 0000 0000 1000

我想知道设置了什么位(感谢@muddyfish,我将澄清这些数字只会设置一个位),在这种情况下为 3,因为 2^3 = 8。我可以使用 log2 来实现这个,但这似乎可以通过'bit twiddling'技术轻松解决。我也可以像这样遍历所有位:

def getSetBit(num):
    if num == 0:
        return -1

    bit = 0
    while num != 1:
        bit += 1
        num >>= 1

    return bit

# getBitSet(0b100000) == 5
# getBitSet(1) == 0

但是,这对我来说似乎很尴尬并且比它应该的要慢。如果这是唯一的方法,我想我可以忍受它,但如果不是,我会喜欢它。

【问题讨论】:

  • 您只想测试设置为 1 位的值吗?
  • @muddyfish 是的,确实
  • 一般来说,您可以通过在函数调用停止时对适当的常量(0x0000ffff 和 0x0ffff0000 对 32 位整数进行递归屏蔽)对任何固定长度整数(位列表)执行二进制搜索,等等)。这将在 log(n) 时间内为 n 位找到所有设置位 ...(其中 n 是您的语言中某些受支持的整数类型的长度,以位为单位)。对于 n 位整数数组,它可以在 m*log(n) 时间工作,这实际上是长整数数组的线性时间(因为 log(n) 对于任何固定位长度都是恒定的)。

标签: python bit-manipulation bit


【解决方案1】:

要获得最高位组的位数,您可以使用

int.bit_length()-1

这比使用math.log() 或您发布的其他功能要高效得多

编辑:

根据要求,发布 timeit 结果:

python -m timeit -s 'import math;x=100' 'int(math.log(x,2))'

1000000 次循环,3 次中的最佳:每个循环 0.5 微秒

python -m timeit -s 'i = 100' 'i.bit_length()-1'

10000000 次循环,3 次中的最佳:每个循环 0.106 微秒

此外,使用 math.log 将产生高于 2**29 的值的不准确结果。

【讨论】:

  • 这是一个很好的答案,但是你有什么更独立于语言的吗?
  • 好吧,例如 C 本身就没有这个功能,以及其他语言。有什么方法可以做到这一点,而大多数其他语言也可以做到?
  • 带移位的while循环?我不会用我不懂的语言来了解
  • 这个其实是错的,你需要num.bit_length() -1
  • 我想我会查看源代码,看看 Pythonistas 为 int.bit_length() 做了什么。谢谢!
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 2018-11-18
  • 2016-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多