Вопрос

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

Это было полезно?

Решение

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

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-битного значения.

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

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

Другие советы

Как продолжение ответа @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
}

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

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

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

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

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

Ответ Кристофера Джонсона очень хорош, если вам нравится работать с такими отдельными полями.Я предпочитаю облегчить чтение кода, используя битовые поля в 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) {}
  ...
}

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

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

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

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

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
}

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

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

int MY_FLAG = 0x0001;
if ((value & MY_FLAG) == MY_FLAG)
    doSomething();

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

if (var & 0x08) {
  /* the fourth bit is set */
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top