Проверка определенных бит битовой маски - PullRequest
0 голосов
/ 11 декабря 2018

Я работаю с Bitmasks в python.Насколько я знаю, это массивы целых чисел, которые при распаковке в двоичный формат сообщают вам, какой из 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), вывод функции обнаружить будет «Есть некоторые проблемы», поскольку установлен бит 22:

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

Есть какие-нибудь идеи о том, как улучшить производительность?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Целые числа - это не что иное, как последовательность битов в компьютере.

Итак, если вы получите целое число, скажем: 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.

0 голосов
/ 11 декабря 2018

Я не уверен, что в вашем 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 (список, датакадр и т. Д.), Примените к каждому значению функцию is_ok().

Надеюсь, это поможет!

...