Как проверить мой байт-флаг? - PullRequest
       54

Как проверить мой байт-флаг?

22 голосов
/ 24 сентября 2008

Я использую байт для хранения некоторого флага, например 10101010, и я хотел бы знать, как проверить, что определенный бит находится в 1 или 0.

Ответы [ 10 ]

46 голосов
/ 24 сентября 2008

Вот функция, которую можно использовать для проверки любого желаемого бита:

bool is_bit_set(unsigned value, unsigned bitindex)
{
    return (value & (1 << bitindex)) != 0;
}

Немного объяснений:

Оператор сдвига влево (<<) используется для создания битовой маски. (1 << 0) будет равно 00000001, (1 << 1) будет равно 00000010, (1 << 3) будет равно 00001000 и т. Д. Таким образом, сдвиг 0 проверяет самый правый бит. Сдвиг 31 будет самым левым битом 32-битного значения. </p>

Оператор побитового и (()) дает результат, в котором установлены все биты, равные 1 с обеих сторон. Примеры: 1111 и 0001 = 0001; 1111 и 0010 == 0010; 0000 & 0001 = 0000. Таким образом, выражение (значение & (1 << bitindex)) вернет битовую маску, если связанный бит равен 1 по значению, или вернет 0, если связанный бит равен 0. </p>

Наконец, мы просто проверяем, является ли результат ненулевым. (На самом деле это можно было бы опустить, но я хотел бы сделать это явным.)

6 голосов
/ 24 сентября 2008

Как продолжение ответа @Daoks

При выполнении битовых манипуляций на самом деле помогает получить очень твердое знание битовых операторов .

Также побитовый оператор «И» в C равен &, поэтому вы хотите сделать следующее:

unsigned char a = 0xAA; // 10101010 in hex
unsigned char b = (1 << bitpos); //Where bitpos is the position you want to check

if(a & b) {
    //bit set
}

else {
    //not set
}

Выше я использовал побитовое «И» (& в С), чтобы проверить, был ли установлен конкретный бит или нет. Я также использовал два разных способа составления двоичных чисел. Я настоятельно рекомендую проверить ссылку на Википедию выше.

4 голосов
/ 24 сентября 2008

Ответ Кристофера Джонсона очень хорош, если вам нравится работать с отдельными полями, такими как эта. Я предпочитаю сделать код проще для чтения, используя битовые поля в C.

Например:

struct fieldsample
{
  unsigned short field1 : 1;
  unsigned short field2 : 1;
  unsigned short field3 : 1;
  unsigned short field4 : 1;
}

Здесь у вас есть простая структура с четырьмя полями, каждое размером 1 бит. Затем вы можете написать свой код, используя простой доступ к структуре.

void codesample()
{
  //Declare the struct on the stack.
  fieldsample fields;
  //Initialize values.
  fields.f1 = 1;
  fields.f2 = 0;
  fields.f3 = 0;
  fields.f4 = 1;
  ...
  //Check the value of a field.
  if(fields.f1 == 1) {}
  ...
}

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

4 голосов
/ 24 сентября 2008

Если вы используете C ++ и стандартная библиотека разрешена, я бы посоветовал хранить ваши флаги в битах:

#include <bitset>
//...
std::bitset<8> flags(someVariable);

тогда вы можете проверять и устанавливать флаги с помощью оператора индексации [].

4 голосов
/ 24 сентября 2008

Вы можете использовать оператор AND. Например, у вас есть: 10101010, и вы хотите проверить третий бит, который вы можете сделать: (10101010 И 00100000), и если вы получите 00100000, вы знаете, что у вас есть флаг в третьей позиции к 1.

2 голосов
/ 24 сентября 2008

Пока что никто не ошибался, но дать метод проверки произвольного бита:

int checkBit( byte in, int bit )
{
  return in & ( 1 << bit );
}

Если функция возвращает ненулевое значение, бит установлен.

1 голос
/ 24 сентября 2008

Традиционно, чтобы проверить, установлен ли младший бит, это будет выглядеть примерно так:

int MY_FLAG = 0x0001;
if ((value & MY_FLAG) == MY_FLAG)
    doSomething();
1 голос
/ 24 сентября 2008

вы можете делать, как говорит Даок, и вы делаете побитовое ИЛИ к результату предыдущей операции AND. В этом случае у вас будет конечный результат 1 или 0.

1 голос
/ 24 сентября 2008
byte THIRDBIT = 4; // 4 = 00000100 i.e third bit is set

int isThirdBitSet(byte in) {
 return in & THIRDBIT; // Returns 1 if the third bit is set, 0 otherwise
}
0 голосов
/ 24 сентября 2008

Используйте побитовое (не логично!) И для сравнения значения с битовой маской.

if (var & 0x08) {
  /* the fourth bit is set */
}
...