it-swarm.com.ru

C/C++ проверяет, установлен ли один бит, то есть переменная int

int temp = 0x5E; // in binary 0b1011110.

Есть ли такой способ проверить, равен ли бит 3 в температуре 1 или 0 без смещения и маскирования битов.

Просто хочу узнать, есть ли какая-то встроенная функция для этого, или я вынужден написать ее сам.

88
Milan

В C, если вы хотите скрыть битовые манипуляции, вы можете написать макрос:

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

и используйте это так:

CHECK_BIT(temp, 3)

В C++ вы можете использовать std :: bitset .

139
mouviciel

Проверьте, установлен ли бит N (начиная с 0):

temp & (1 << N)

Для этого нет встроенной функции.

72
Joao da Silva

Я бы просто использовал std :: bitset, если это C++. Просто. Прямодушная. Нет шансов на глупые ошибки.

typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);

или как насчет этой глупости

template<unsigned int Exp>
struct pow_2 {
    static const unsigned int value = 2 * pow_2<Exp-1>::value;
};

template<>
struct pow_2<0> {
    static const unsigned int value = 1;
};

template<unsigned int Pos>
bool is_bit_set(unsigned int value)
{
    return (value & pow_2<Pos>::value) != 0;
} 

bool result = is_bit_set<2>(value);
21
user21714

Согласно этому описанию битовых полей , существует метод для определения и доступа к полям напрямую. Пример в этой записи:

struct preferences {
    unsigned int likes_ice_cream : 1;
    unsigned int plays_golf : 1;
    unsigned int watches_tv : 1;
    unsigned int reads_books : 1;
}; 

struct preferences fred;

fred.likes_ice_cream = 1;
fred.plays_golf = 1;
fred.watches_tv = 1;
fred.reads_books = 0;

if (fred.likes_ice_cream == 1)
    /* ... */

Также там есть предупреждение:

Однако элементы-биты в структурах имеют практические недостатки. Во-первых, порядок расположения битов в памяти зависит от архитектуры, и правила заполнения памяти варьируются от компилятора к компилятору. Кроме того, многие популярные компиляторы генерируют неэффективный код для чтения и записи элементов битов, и существуют потенциально серьезные проблемы безопасности потоков, связанные с битовыми полями (особенно в многопроцессорных системах), из-за того, что большинство машин не могут манипулировать произвольными наборами битов в памяти, но должен вместо этого загружать и хранить целые слова.

11
gimel

Да, я знаю, что не могу {"have" сделать это таким образом. Но я обычно пишу:

    /* Return type (8/16/32/64 int size) is specified by argument size. */
template<class TYPE> inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }

template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y)
{ return 0 != (x & y); }

Например.:

IsBitSet( foo, BIT(3) | BIT(6) );  // Checks if Bit 3 OR 6 is set.

Среди прочего, этот подход:

  • Приспосабливает 8/16/32/64 битных целых числа.
  • Обнаруживает вызовы IsBitSet (int32, int64) без моего ведома и согласия.
  • Встроенный шаблон, поэтому нет необходимости вызывать функцию.
  • const & ссылки, поэтому ничего не нужно дублировать/копировать needs. И мы гарантируем, что компилятор подберет любые опечатки, которые пытаются изменить аргументы.
  • 0! = Делает код более понятным и понятным. Основным моментом при написании кода всегда является четкое и эффективное общение с другими программистами, в том числе с меньшими навыками.
  • Хотя это не применимо к этому конкретному случаю ... В общем случае шаблонные функции избегают проблемы оценки аргументов несколько раз. Известная проблема с некоторыми макросами #define. 
    Например: # определить ABS (X) (((X) <0)? - (X): (X)) 
    ABS (я ++);
10
Mr.Ree

То, что выбранный ответ делает на самом деле неправильно. Приведенная ниже функция вернет битовую позицию или 0 в зависимости от того, активирован ли бит на самом деле. Это не то, о чем просил плакат.

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

Вот что изначально искал плакат. Приведенная ниже функция вернет 1 или 0, если бит активирован, а не позиция.

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
8
shocker92

Вы можете использовать Bitset - http://www.cppreference.com/wiki/stl/bitset/start .

5
yawmark

Используйте std :: bitset

#include <bitset>
#include <iostream>

int main()
{
    int temp = 0x5E;
    std::bitset<sizeof(int)*CHAR_BITS>   bits(temp);

    // 0 -> bit 1
    // 2 -> bit 3
    std::cout << bits[2] << std::endl;
}
4
Martin York

Существует, а именно _bittest внутренняя инструкция.

4
Dave Van den Eynde

я пытался прочитать 32-разрядное целое число, которое определило флаги для объекта в PDF, и это не сработало для меня

что исправило это изменило определение:

#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))

операнд & возвращает целое число с флагами, которые оба имеют в 1, и это не было приведено должным образом к булевому, это добилось цели

3
Ismael

Я использую это:

#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )

где "pos" определяется как 2 ^ n (например, 1,2,4,8,16,32 ...)

Возвращает: 1 если верно 0 если ложь

2
AnthropicDream

Вы могли бы «смоделировать» смещение и маскировку: if ((0x5e/(2 * 2 * 2))% 2) ...

2
Leonidas

Для низкоуровневого решения для x86 используйте код операции x86 TEST .

Ваш компилятор должен превратить _bittest в это, хотя ...

2
jheriko

Почему бы не использовать что-нибудь простое?

uint8_t status = 255;
cout << "binary: ";

for (int i=((sizeof(status)*8)-1); i>-1; i--)
{
  if ((status & (1 << i)))
  {
    cout << "1";
  } 
  else
  {
    cout << "0";
  }
}

Результат: двоичный файл: 11111111

1
zeilja

если вы просто хотите по-настоящему жестко закодированный способ:

 #define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )

обратите внимание, что это зависит от hw и предполагает, что этот битовый порядок 7654 3210, а var равен 8 битам.

#include "stdafx.h"
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
int _tmain(int argc, _TCHAR* argv[])
{
    int temp =0x5E;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x00;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x04;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0xfb;
    printf(" %d \n", IS_BIT3_SET(temp));
    scanf("waitng %d",&temp);

    return 0;
}

Результаты в:

1 0 1 0

0
simon

Одним из подходов будет проверка в следующих условиях:

if ( (mask >> bit ) & 1)

Программа объяснения будет:

#include <stdio.h>

unsigned int bitCheck(unsigned int mask, int pin);

int main(void){
   unsigned int mask = 6;  // 6 = 0110
   int pin0 = 0;
   int pin1 = 1;
   int pin2 = 2;
   int pin3 = 3;
   unsigned int bit0= bitCheck( mask, pin0);
   unsigned int bit1= bitCheck( mask, pin1);
   unsigned int bit2= bitCheck( mask, pin2);
   unsigned int bit3= bitCheck( mask, pin3);

   printf("Mask = %d ==>>  0110\n", mask);

   if ( bit0 == 1 ){
      printf("Pin %d is Set\n", pin0);
   }else{
      printf("Pin %d is not Set\n", pin0);
   }

    if ( bit1 == 1 ){
      printf("Pin %d is Set\n", pin1);
   }else{
      printf("Pin %d is not Set\n", pin1);
   }

   if ( bit2 == 1 ){
      printf("Pin %d is Set\n", pin2);
   }else{
      printf("Pin %d is not Set\n", pin2);
   }

   if ( bit3 == 1 ){
      printf("Pin %d is Set\n", pin3);
   }else{
      printf("Pin %d is not Set\n", pin3);
   }
}

unsigned int bitCheck(unsigned int mask, int bit){
   if ( (mask >> bit ) & 1){
      return 1;
   }else{
      return 0;
   }
}

Результат:

Mask = 6 ==>>  0110
Pin 0 is not Set
Pin 1 is Set
Pin 2 is Set
Pin 3 is not Set
0
Michi

Хотя сейчас довольно поздно, чтобы ответить, есть простой способ узнать, установлен N-й бит или нет, просто используя математические операторы POWER и MODULUS.

Допустим, мы хотим знать, установлен ли «temp» N-й бит или нет. Следующее логическое выражение даст true, если бит установлен, 0 в противном случае.

  • (временная температура 2 ^ N + 1> = 2 ^ N)

Рассмотрим следующий пример:

  • int temp = 0x5E; // в двоичном виде 0b1011110 // BIT 0 равен LSB

Если я хочу знать, установлен 3-й бит или нет, я получаю

  • (94 МОДУЛЬ 16) = 14> 2 ^ 3

Таким образом, выражение возвращает истину, указывая, что 3-й бит установлен.

0
Ouroboros