【问题标题】:Checking specific bits of a bitmask检查位掩码的特定位
【发布时间】:2018-12-11 12:23:00
【问题描述】:

我正在与Bitmaskspython 合作。据我所知,这些是整数数组,当它们被解压缩为二进制格式时,它们会告诉您为数组中的给定元素设置了 32 位中的哪一个(=1)。

我想知道检查是否为数组的任何元素设置了 4 个特定位的最快方法。我不关心其余的。我尝试了以下解决方案,但速度不够快:

def detect(bitmask, check=(18,22,23,24), bits=32):
    boolmask = np.zeros(len(bitmask), dtype=bool)
    for i, val in enumerate(bitmask):    
        bithost = np.zeros(bits, dtype='i1')
        masklist = list(bin(val)[2:])
        bithost[:len(masklist)] = np.flip(masklist,axis=0)
        if len(np.intersect1d(np.nonzero(bithost)[0] ,check)) != 0:
            boolmask[i] = True        
        else: 
            boolmask[i] = False
    if any(boolmask):
        print("There are some problems")
    else:
        print("It is clean")

例如,如果给定的 bitmask 包含整数 24453656 (1011101010010001000011000 in binary),则函数 detect 的输出将是“存在一些问题”,因为位 22已设置:

bit: ...  20, 21, 22, 23, 24,...  
mask: ... 0,  0,  1,  0,  0,...

关于如何提高性能的任何想法?

【问题讨论】:

  • 所以你要检查,如果对于给定的整数,你要检查的任何位被设置,如果其中任何一个被设置,你想说有问题吗?
  • 是的,就是这样@Gnudiff。对不起,如果我的问题不够清楚。
  • 在这种情况下我的答案应该是正确的

标签: python numpy bit-manipulation bit bitmask


【解决方案1】:

整数只是计算机中的位序列。

所以,如果你得到整数,假设:333 它是计算机的 101001101 位序列。它不需要任何拆包。它位。

因此,如果掩码也是整数,则不需要任何解包,只需对其进行按位运算即可。查看wikipedia 了解这些工作原理的详细信息。

为了检查是否有任何位 xyz 设置为整数 abc,您可以: (abc & xyz) > 0。如果您绝对需要将掩码检查为位元组,请进行一些打包,如下所示:

def detect(bitmask,check=(18,22,23,24)):
    checkmask=sum(2**x for x in check)
    if (bitmask & checkmask) > 0:
        print "There are some problems"
    else:
        print "Everything OK"

请注意,位掩码从基于 0 的位索引开始。第一位是位 0。

【讨论】:

  • @JTM 差不多。它应该是位掩码和检查掩码。已修复,谢谢
  • Ups,我不小心删除了我之前的评论。通过此修复,它可以正常工作且速度更快。谢谢!
  • @JTM 如果您的问题得到您满意的回答,欢迎您接受答案。
【解决方案2】:

我不确定您的 bitmask 参数中的内容。不管怎样,你应该使用位运算符。

像这样制作一个位掩码:

def turn_bits_on(bits):
    n = 0
    for k in bits:
        n = (n | (1 << (k - 1))) if k > 0 else n
    return n

bits_to_check = turn_bits_on([18, 22, 23, 24])

然后,对于单个数字,您可以通过以下方式检测:

def is_ok(value, mask):
    return not (value & mask)

print(is_ok(24453656, bits_to_check))

最后,根据您的bitmask 值是什么(列表、DataFrame 等),将is_ok() 函数应用于每个值。

希望这会有所帮助!

【讨论】:

  • 非常感谢。正如您和@Gnudiff 所说,关键在于按位运算符。我已经测试了这两种方法,但他的执行速度似乎更快。
猜你喜欢
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
相关资源
最近更新 更多