2016-12-15 3 views
2

Мне нужно написать функцию, которая получит 2 байт и логическое значение:Бит с учетом длиной

filter(int length, uint16_t* A, uint16_t* B, bool checkByZeros) 

необходимой логика: длины количества бит для проверки (например, если длина = 9 байтовый массив будет содержать 2 байта) , если это checkByZeros False

функция возвращает true если:

all the bytes set (=1) in A are also set in B 

в примере (длина = 9):

checkByZeros=True, A:000001111, B:000001111 ==> True 
checkByZeros=True, A:000001111, B:000011111 ==> True 
checkByZeros=True, A:000001111, B:000000111 ==> False 

, если это checkByZeros False

функция возвращает true если: все байты не-множество (= 0) в А также not- установить в B в примере:

checkByZeros=False, A:000001111, B:000001111 ==> True 
checkByZeros=False, A:000001111, B:000011111 ==> False 
checkByZeros=False, A:000001111, B:000000111 ==> True 

реализация вполне naiive, если я перебираю бит за битом байта, но мне нужно быстрее немного OPERAT ионного метода. Любые предложения? Я немного потерян, потому что, рассматривая разную длину, бит-операции должны игнорировать биты, которые расположены после длины

+1

Вы вводите код в 'c' или' C++ '? Это разные языки, и ни один из них не имеет встроенного типа 'byte' – alexeykuzmin0

+1

@ alexeykuzmin0 Я на C++ и в настоящее время вместо байта [] Я использую uint16_t, поэтому значение max max равно 16, но вскоре я изменю реализацию на использовать ** uint8_t * array ** anyways AFAIK операция бит может быть выполнена на любом типе – KitBag

+0

Насколько вы знаете о [побитовых операторах] (http://www.cprogramming.com/tutorial/bitwise_operators.html)? Кажется, что для первого случая (когда 'checkByZeros == true') достаточно простого маскирования и сравнения для равенства должно быть достаточно (' A & B == A'). Этот же метод можно было использовать и для второго случая (с помощью побитового оператора дополнения). –

ответ

2

Вы можете использовать побитовые операторы для проверки нескольких бит одновременно. Например, если вы хотите, чтобы проверить, что все установленные биты a имеют соответствующие установленные биты b, можно написать следующее:

(~b & a & mask) == 0 

Здесь ~b является побитовой инверсией b, которая имеет 1 с на все места где b имеет 0 с, поэтому, ~b & a будет 1 в каком-то положении, если и только если a имеет 1 в этом положении и b имеет 0, что это именно то, что нам нужно.

Маска (1 << length) - 1, то есть, содержит 1 всего length низших разрядов, и, таким образом, помогает нам игнорировать самые высокие биты результата, которые мы не хотим, чтобы проверить.

Этот метод позволяет проверить до 64 бит (длина long long) сразу. Если checkByZeros - true, вы можете написать аналогичный код.

+0

Каков код в случае проверки нулем = true? делать то же самое без ~ b ?? – KitBag

+0

'b & ~ a & mask', логика точно такая же, как в первом случае – alexeykuzmin0

0
uint16_t temp; 

if(checkByZeroes) 
{ 
    temp = *B | *A; // ignore 0's in B which are not in a 
} 
else 
{ 
    temp = *B & *A; // ignore 1's in B which are not in a 
} 

return temp == *A; 
+0

Как насчет длины? – KitBag

+0

Я предложил это, считая, что бит слева от длины всегда будет равен нулю. Если это так, эти биты не повлияют на результат. Кроме того, вам нужна маска, как сказал alexeskuzmin0. –

+0

Жаль, что я не смог бы поддержать вас @ t.m. – KitBag

Смежные вопросы