Pregunta

Utilizo un byte para almacenar alguna bandera como 10101010y me gustaría saber cómo verificar que un bit específico esté en 1 o 0.

¿Fue útil?

Solución

Aquí hay una función que se puede utilizar para probar cualquier bit deseado:

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

Un poco de explicación:

El operador de desplazamiento a la izquierda (<<) se utiliza para crear una máscara de bits.(1 << 0) será igual a 00000001, (1 << 1) será igual a 00000010, (1 << 3) será igual a 00001000, etc.Entonces, un desplazamiento de 0 prueba el bit más a la derecha.Un desplazamiento de 31 sería el bit más a la izquierda de un valor de 32 bits.

El operador bit a bit (&) da un resultado en el que se establecen todos los bits que son 1 en ambos lados.Ejemplos:1111 y 0001 = 0001;1111 y 0010 == 0010;0000 y 0001 = 0000.Entonces, la expresión (valor & (1 << bitindex)) devolverá la máscara de bits si el valor del bit asociado es 1, o devolverá 0 si el bit asociado es 0.

Finalmente, simplemente verificamos si el resultado es distinto de cero.(Esto podría omitirse, pero me gusta hacerlo explícito).

Otros consejos

Como una extensión de la respuesta de @Daoks

Al manipular bits, en realidad ayuda a tener un conocimiento muy sólido de operadores bit a bit.

Además, el operador "Y" bit a bit en C es &, entonces lo que quieres hacer es:

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
}

Arriba utilicé el "Y" bit a bit (& en C) para verificar si un bit en particular estaba configurado o no.También utilicé dos formas diferentes de formular números binarios.Le recomiendo encarecidamente que consulte el enlace de Wikipedia de arriba.

Puede utilizar un operador AND.Ejemplo tienes:10101010 y quieres comprobar el tercer bit, puedes hacer:(10101010 Y 00100000) y si te sale 00100000 sabes que tienes la bandera en la tercera posición al 1.

Si está utilizando C++ y la biblioteca estándar está permitida, le sugiero que almacene sus indicadores en un conjunto de bits:

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

entonces puede verificar y configurar banderas usando el operador de indexación [].

La respuesta de Kristopher Johnson es muy buena si te gusta trabajar con campos individuales como este.Prefiero hacer que el código sea más fácil de leer usando campos de bits en C.

Por ejemplo:

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

Aquí tienes una estructura simple con cuatro campos, cada uno de 1 bit de tamaño.Luego puede escribir su código utilizando un acceso a estructura simple.

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) {}
  ...
}

Obtiene la misma ventaja de tamaño pequeño, además de código legible porque puede darle a sus campos nombres significativos dentro de la estructura.

Nadie se ha equivocado hasta ahora, pero para dar un método para comprobar un bit arbitrario:

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

Si la función devuelve un valor distinto de cero, el bit está establecido.

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
}

puedes hacer lo que dice Daok y hacer poco a poco OR al resultado de la operación AND anterior.En este caso tendrás un resultado final de 1 o 0.

Tradicionalmente, para comprobar si el bit más bajo está configurado, esto se verá así:

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

Utilice un bit a bit (¡no lógico!) y compare el valor con una máscara de bits.

if (var & 0x08) {
  /* the fourth bit is set */
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top