Checking specific bits of a bitmask

一笑奈何 提交于 2019-12-24 10:23:03

问题


I am working with Bitmasks in python. As far as I know, these are arrays of integers that when they are unpacked into binary format they tell you which of the 32 bits are set (=1) for a given element in the array.

I would like to know the fastest way to check whether 4 specific bits are set or not for any element of an array. I do not care about the rest. I have tried the following solution but it is not fast enough for my purpose:

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")

For example, if a given bitmask contains the integer 24453656 (1011101010010001000011000 in binary), the output of function detect would be "There are some problems" since bit 22 is set:

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

Any ideas on how to improve the performance?


回答1:


Integers are nothing but sequence of bits in the computer.

So, if you get integer, let's say: 333 it is a sequence of bits 101001101 to the computer. It doesn't need any unpacking into bits. It is bits.

Therefore, if the mask is also an integer, you don't need any unpacking, just apply bitwise operations to it. Check wikipedia for details of how these work.

In order to check if ANY of the bits xyz are set in an integer abc, you do: (abc & xyz) > 0. If you absolutely need checking mask to be a tuple of bit places, you do some packing, like this:

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"

Note that bitmasks start with 0 based bit indices. First bit is bit 0.




回答2:


I am not sure what's in your bitmask argument. Regarless, you should probably use bitwise operators.

Make a bit mask like this:

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])

Then, for a single number, you can detect with:

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

print(is_ok(24453656, bits_to_check))

Finally, depending on what your bitmask value is (a list, a DataFrame, etc), apply the is_ok() function to each value.

Hope this helps!



来源:https://stackoverflow.com/questions/53724160/checking-specific-bits-of-a-bitmask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!