Respostas:
Em C, se você deseja ocultar a manipulação de bits, pode escrever uma macro:
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
e use-o desta forma para verificar o enésimo bit da extremidade direita:
CHECK_BIT(temp, n - 1)
Em C ++, você pode usar std :: bitset .
!= 0
é verdade, então por que se preocupar? 1
é exatamente tão verdadeiro quanto 0.1415
!
std::bitset
, realmente? Claro, ao invés de fazer um pequeno trabalho (e potencialmente alguns modelos realmente bons) para verificar um único bit, use um contêiner inchado que armazena (na minha implementação) cada 'bit' em um de outra forma não utilizado unsigned long
. Que desperdício de espaço!
Verifique se o bit N (começando em 0) está definido:
temp & (1 << N)
Não há função embutida para isso.
1 << 0
?? Desculpe, confuso.
1<<0
, que é 1 sem qualquer deslocamento (deslocamento 0), que é1<<0 == 1
Eu usaria apenas um std :: bitset se for C ++. Simples. Direto. Sem chance para erros estúpidos.
typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);
ou que tal essa bobagem
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);
std::bitset<CHAR_BIT * sizeof(int)>
para ser ainda mais correto
Sim, eu sei que não "tenho" que fazer desta forma. Mas costumo escrever:
/* 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); }
Por exemplo:
IsBitSet( foo, BIT(3) | BIT(6) ); // Checks if Bit 3 OR 6 is set.
Entre outras coisas, esta abordagem:
O que a resposta selecionada está fazendo está realmente errado. A função abaixo retornará a posição do bit ou 0 dependendo se o bit está realmente habilitado. Não era isso que o cartaz estava pedindo.
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
Aqui está o que o pôster estava procurando originalmente. A função abaixo retornará 1 ou 0 se o bit estiver habilitado e não a posição.
#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
bool has_feature = CHECK_BIT(register, 25);
bom saber que eu poderia fazer isso sem a dupla negação.
De acordo com esta descrição de campos de bits , existe um método para definir e acessar campos diretamente. O exemplo nesta entrada é:
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)
/* ... */
Além disso, há um aviso lá:
No entanto, membros de bits em estruturas têm desvantagens práticas. Primeiro, a ordenação dos bits na memória depende da arquitetura e as regras de preenchimento da memória variam de compilador para compilador. Além disso, muitos compiladores populares geram código ineficiente para ler e gravar membros de bits, e há problemas de segurança de thread potencialmente graves relacionados a campos de bits (especialmente em sistemas multiprocessadores) devido ao fato de que a maioria das máquinas não pode manipular conjuntos arbitrários de bits na memória, mas, em vez disso, deve carregar e armazenar palavras inteiras.
Você pode usar um Bitset - http://www.cppreference.com/wiki/stl/bitset/start .
Use 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;
}
temp
precisa ser refletido para torná-lo "big-endian"?
Eu uso isso:
#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )
onde "pos" é definido como 2 ^ n (ig 1,2,4,8,16,32 ...)
Retorna: 1 se verdadeiro 0 se falso
4 = 2^(3-1)
para a posição de bit 3, uma vez que era parte da questão.
eu estava tentando ler um inteiro de 32 bits que definia os sinalizadores de um objeto em PDFs e isso não estava funcionando para mim
o que consertou foi mudar a definição:
#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))
o operando & retorna um inteiro com os sinalizadores que ambos têm em 1, e não estava convertendo corretamente em booleano, isso funcionou
!= 0
faria o mesmo. Não sei como as instruções de máquina geradas podem ser diferentes.
Você pode "simular" mudança e mascaramento: if ((0x5e / (2 * 2 * 2))% 2) ...
Por que não usar algo tão simples como isso?
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";
}
}
SAÍDA: binário: 11111111
std::cout << (((status & (1 << i)) ? '1' : '0');
. Você deve usar a CHAR_BIT
constante de em <climits>
vez de codificar 8 bits, embora, neste caso, saiba que o resultado será 8 de qualquer maneira, já que está usando umuint8_t
se você quer apenas uma forma real de código:
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
observe que este depende de hw e assume esta ordem de bits 7654 3210 e var é de 8 bits.
#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;
}
Resulta em:
1 0 1 0
Embora seja muito tarde para responder agora, há uma maneira simples de descobrir se o enésimo bit está definido ou não, simplesmente usando os operadores matemáticos POWER e MODULUS.
Digamos que queremos saber se 'temp' tem o enésimo bit definido ou não. A seguinte expressão booleana fornecerá verdadeiro se o bit for definido, 0 caso contrário.
Considere o seguinte exemplo:
Se eu quiser saber se o terceiro bit está definido ou não, recebo
Portanto, a expressão retorna verdadeiro, indicando que o terceiro bit está definido.
Uma abordagem será verificar dentro da seguinte condição:
if ( (mask >> bit ) & 1)
Um programa de explicação será:
#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;
}
}
Resultado:
Mask = 6 ==>> 0110 Pin 0 is not Set Pin 1 is Set Pin 2 is Set Pin 3 is not Set
#define CHECK_BIT(var,pos) ((var>>pos) & 1)
pos - posição do bit começando de 0.
retorna 0 ou 1.
Eu faço isso:
LATGbits.LATG0 = ((m & 0x8)> 0); // para verificar se o bit-2 de m é 1