elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Probar si varios bits están "seteados"
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Probar si varios bits están "seteados"  (Leído 1,913 veces)
huchoko

Desconectado Desconectado

Mensajes: 97


Ver Perfil WWW
Probar si varios bits están "seteados"
« en: 15 Junio 2019, 07:17 am »

Buenas, tal cual en el título, nececito probar si varios bits de una variable estan "seteados" osea valen 1 (como saben bit 0 o 1).
Puedo comprobar un solo bit con:
Código
  1. if (variableacomprobar & indexdelbit) {
  2.    /* etc... */
  3. }
  4.  
Pero como lo hago para varios a la vez?
Por ejemplo, tengo una varible con dos bits que quiero comprobar a la vez:
Bits 7 y 6: quiero comprobar si el uno (bit 7) y el cero (bit 6) valen 1 y viceversa. Osea:
Código:
|15...|7|6|5|4|3|2|1|0|
       | |
       1 0
     Ó
       0 1
Espero haberme explicado bien, cualquier confusión preguntenme por aclaración. :)


En línea

@XSStringManolo
Hacker/Programador
Colaborador
***
Desconectado Desconectado

Mensajes: 2.397


Turn off the red ligth


Ver Perfil WWW
Re: Probar si varios bits están "seteados"
« Respuesta #1 en: 15 Junio 2019, 08:27 am »

Lo puedes hacer de mucha maneras.
Guardas los bit en una cadena. Te inventas otra cadena para comparar. Recorres ambas cadenas con un bucle for y las comparas.
Ejemplo:
Código
  1. string cadena1 = "10001011";
  2. string cadenaParaComprobar = "11111111";
  3.  
  4. for (int i = 0; i < cadena1.size(); ++i)
  5. {
  6.     if (cadena1[i] == cadenaParaComprobar[i])
  7.      {
  8.     cout << "El bit numero " << i << " esta set" <<endl;
  9.      }
  10. }

Puedes usar los operadores bitwise diseñhados para eso de 200 maneras distintas para hacer lo mismo. Se suelen usar para comparar los bits, sumarlos, restarlos, desplazarlos, etc.


Pd: Te pongo ejemplos de los operadores.
Citar
resultado = X & Y;
X= 00001111
Y= 00011000

El resultado será:
00001000

Citar
resultado = X | Y;
X= 00001111
Y= 00011000

El resultado será:
00011111

Citar
resultado = X ^ Y;
X= 00001111
Y= 00011000

El resultado será:
00010111

Citar
resultado = 1 << 1;

El resultado será:
00000010
Es decir, 2 en decimal.

Citar
resultado = 1 >> 1;

El resultado será:
00000000
0 en decimal. Hechó al uno fuera y no había bits para guardar su valor. Se perdió.


« Última modificación: 15 Junio 2019, 08:45 am por string Manolo » En línea

Mi perfil de patrocinadores de GitHub está activo! Puedes patrocinarme para apoyar mi trabajo de código abierto 💖

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: Probar si varios bits están "seteados"
« Respuesta #2 en: 15 Junio 2019, 08:47 am »

https://en.wikipedia.org/wiki/Bitwise_operation

Supongamos que te interesa comprobar el tercer y el octavo bit. Siendo mask1 0x4 (100b = 0x4) y mask2 0x80 (10000000b = 0x80 = 128).

Código
  1. if ( (var & mask1) && !(var & mask2) )
  2. ...
  3. else if ( !(var & mask1) && (var & mask2) )
  4. ...

O:
Código
  1. if ( (var & (mask1 | mask2)) == mask1)
  2. ...
  3. else if ( (var & (mask1 | mask2)) == mask2)
  4. ...

Se puede hacer de muchas maneras, con diferente grado de optimizacion.
« Última modificación: 15 Junio 2019, 09:21 am por Eternal Idol » En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
@XSStringManolo
Hacker/Programador
Colaborador
***
Desconectado Desconectado

Mensajes: 2.397


Turn off the red ligth


Ver Perfil WWW
Re: Probar si varios bits están "seteados"
« Respuesta #3 en: 15 Junio 2019, 09:01 am »

Es de una traducción al español que estoy haciendo del libro de Apress Learn C++ for game development.

Capitulo 18: La STL. bitset.

El bitset no es exactamente un contenedor, se parece mas a un tipo de dato de STL.
No es compatible con iteradores, bucles for basados en rango o algoritmos STL.
Se utiliza para seguir valores booleanos en un set combinado. El metodo tradicional
para conseguir el mismo resultado son las flags implementadas usando operadores
bitwise y shifts.

Una de las diferencias de bitset con respecto a los contenedores de la STL es que no
necesitas especificar un tipo para el bitset.

Especializando bitset:

#include <bitset>

using namespace std;

namespace
{
   const unsigned int NUMERO_DE_BITS = 5
}

using MiBitset = bitset<NUMERO_DE_BITS>;



Diferentes constructores para bitset:

MiBitset DefaultConstructor; //Inicializa todos los bits a 0.
MiBitset UnsignedLongConstructor{0x17}; //Valor literal
MiBitset StringConstructor{ string{ "11011"} };



Trabajando con bitsets.
Un biset proporciona metodos para realizar un buen numero de operaciones
diferentes. Estos pueden dividirse entre metodos que preguntan sobre el
estado actual del bitset, y metodos usados para alterar los bits.

cout << boolalpha;

cout << "Tamanho del bitset: " << StringConstructor.size() << endl;
cout << "Numero de bits asignados: " << StringConstructor.count() << endl;

cout << "Hay algun bit asignado? " << StringConstructor.any() << endl;
cout << "Estan todos los bit asignados? "<<StringConstructor.all() << endl;
cout << "No hay bits asignados? " << StringConstructor.none() << endl;

for (unsigned int i = 0; i < StringConstructor.size(); ++i)
{
   cout << "Bit " << i << " Valor: " << StringConstructor << endl;
   cout << "Bit " << i << " test: " << stringConstructor.test(i) << endl;
}

El metodo size retorna el valor que le pasamos en la plantilla. El metodo
count retorna el numero de bit a los que le asignamos true.



Hay tres metodos para alterar los valores almacenados en bitset:

StringConstructor.set(1, false);
StringConstructor.set(1);
StringConstructor.set();

StringConstructor.reset(0);
StringConstructor.reset();

StringConstructor.flip(4);  
StringConstructor.flip();


El primer ejemplo utiliza el index de un bit y el valor a asignarle a ese bit.
El segundo utiliza solo un index y asigna 1 al bit correspondiente.
El tercero asigna 1 a todos los bits en el set.
El metodo reset hace lo mismo pero en vez de unos, asigna ceros.
El metodo flip cambia los unos por ceros y los ceros por unos. En caso de
indicarle un index, solo cambiara el bit que se encuentre en ese index.
En línea

Mi perfil de patrocinadores de GitHub está activo! Puedes patrocinarme para apoyar mi trabajo de código abierto 💖

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Probar si varios bits están "seteados"
« Respuesta #4 en: 15 Junio 2019, 16:32 pm »

Primero, aclarar, tú lo quieres es probar si varios bits están todos encendidos o ninguno, porque probarlos individualmente ya lo sabes hacer, ¿cierto?

La forma más simple sería (suponiendo que mascara1, mascara2, etc. contienen cada una 1 bit a probar):

Código
  1. if ((variable & mascara1) && (variable & mascara2) &&  ...
Pero si son muchos bits a probar quedaría una condición larguísima y tendrías demasiadas operaciones. Mejor preparar una máscara combinada y hacer algo así:

Código
  1. mascara = mascara1 | mascara2 | ...
  2.  
  3. // Todos on
  4. if ( (variable & mascara) == mascara)
  5. ...
  6. // Todos off
  7. if (!(variable & mascara))
En línea

Loretz

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Probar si varios bits están "seteados"
« Respuesta #5 en: 15 Junio 2019, 16:51 pm »

Si lo que necesitas es saber si está activo el bit 6 o el 7, pero no ambos a la vez, y no te importa cual de los dos, siempre que sea uno y solo uno de ellos el que esté activo, podrías hacer:

[EDITO:]
Código:
   unsigned var = 182;         // 1011 0110
    unsigned mask6 = 0x40;      // 0100 0000
    unsigned mask7 = 0x80;      // 1000 0000

    bool res = (var & mask6 || var & mask7) && !(var & mask6 && var & mask7);

En C++ puedes usar std::bitset también, que es más fácil para todos.
« Última modificación: 15 Junio 2019, 17:46 pm por Loretz » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines