Найти, если каждый четный бит установлен в 0, используя побитовые операторы - PullRequest
6 голосов
/ 29 августа 2011

У меня 32-битный int, я могу получить к нему доступ только 8 бит за раз. Мне нужно выяснить, установлен ли каждый четный бит на 0, и вернуть 0, если оно истинно, и 1 в противном случае.

Пока что я собираюсь разбить свой int с помощью сдвигов на 4, 8-битные переменные. int a, b, c, d

Теперь я собираюсь их не проверять, поэтому теперь я проверю, установлен ли бит в 1 вместо 0. Для проверки, если он установлен в 1, я буду и их 01010101.

Теперь я не знаю, как определить, установлен ли каждый четный бит на 1. Я не могу использовать циклы if / for / while или любые условные операторы, и мне нужно использовать побитовые операторы. Есть идеи????

Ответы [ 5 ]

5 голосов
/ 29 августа 2011

ОК, поэтому вы создали битовую маску.(01010101)

 if ((value & bit_mask) == bit_mask)

тогда вы знаете, что каждый бит, который был установлен в bit_mask, также установлен в value.

ОБНОВЛЕНИЕ: (после правильного прочтения вопроса)

Вы хотите проверить, установлен ли каждый второй бит на 0. (Не установлено на 1, так как мой неправильный ответ выше проверяет)

Существует два одинаково правильных подхода: мы делаем битовую маску противоположной (10101010)

Затем используем оператор ИЛИ:

if ((value | bit_mask) == bit_mask)

Это проверяет, что каждый бит был нулевымв bit_mask равен нулю в value.

Второй подход заключается в том, чтобы сделать битовую маску одинаковой (01010101) и использовать оператор AND:

if ((value & bit_mask) == 0)

Это проверяет, чтокаждый бит, равный единице в bit_mask, равен нулю в value.

3 голосов
/ 29 августа 2011

РЕДАКТИРОВАТЬ: я был смущен первоначальным вопросом и следовал OP в отрицании - так что в основном это решает обратную проблему.Отредактированное решение Эндрю Шеперда начинается с исходной проблемы и решает ее за 1 шаг.Rudy Velthuis также предлагает интересный подход.

Если ваше байтовое значение AND 01010101 == 01010101, все биты, выбранные маской, равны 1 в исходном значении байта.

В sortof псевдо C:

unsigned char mask = 0x55;

if ((byteval & mask) == mask) {
    printf ("all set");
}

или немного более изящный вариант на основе xor

unsigned char mask = 0x55;

if (!((byteval & mask) ^ mask)) {
    printf ("all set");
}

Кстати, if очень легко избавитьсяконечный результат ...

2 голосов
/ 29 августа 2011

Нет необходимости для проверки каждого отдельного байта на соответствие маске 0x55. Просто "или" байты вместе и проверьте результат по маске:

return ((a | b | c | d) & 0x55 != 0);

Любой четный бит, установленный в 1, приведет к тому, что результат "и" больше не будет 0, поэтому он вернет 1. Если все четные биты равны 0, то возвращается 0.

1 голос
/ 29 августа 2011

логика состоит в том, чтобы использовать арифметические операторы, попробуйте выполнить следующие шаги:

     1. AND the each result with 01010101
     2. then atlast AND all the results,, now if the resulting decimal value is 
      85(decimal(01010101))

, тогда результат верен, иначе результат неправильный,

попробуйте этот пример кода,,

//assume a,b,c,d has the four parts of the bits,,
//do the following for each variable
Ar=a & 01010101
.
.
.
.
Dr=d & 01010101

//now AND all r2 for each variable..
r=Ar & Br & Cr & Dr

//now check the decimal equivalent of r and decide true if it is 85
0 голосов
/ 29 августа 2011

Просто возьмите некоторую целочисленную переменную и сохраните в ней значение.

i= ( a & 0x55 ) + (b & 0x55 ) + ( c & 0x55 ) + (d & 0x55 )

Если все четные биты установлены в ноль, переменная i имеет значение 0, в противном случае больше 0. и все, что не равно нулю, это верно для c.

скажем

 a = 10101010 & 0x55 ( 01010101) which returns zero,masking all odd bits to zero

аналогично

 b & 0x55 and c & 0x55 and d & 0x55 

, и если все они приводят к нулю, тогда переменная i имеет нулевое значение, иначе какое-то другое значение, которое можно считать истинным в c.

...