rotacion - ¿Cómo se usan las banderas bit a bit en C++?
rotacion de bits en c (8)
Conozca sus operarios bit a bit: &, |, ^ y!
En la parte superior de muchos archivos C / C ++ he visto banderas definidas en hexadecimal para enmascarar cada bit.
#define ONE 0x0001
Para ver si un bit está activado, usted Y con 1. Para encenderlo, usted O con 1. Para alternar como un interruptor, XOR con 1.
Según este sitio web, deseo representar un Laberinto con una matriz bidimensional de enteros de 16 bits.
Cada entero de 16 bits necesita contener la siguiente información:
Esta es una forma de hacerlo (esta no es la única manera): una cuadrícula de laberinto de 12x16 se puede representar como una matriz m [16] [12] de enteros de 16 bits. Cada elemento de matriz contendría toda la información para una sola celda correspondiente en la cuadrícula, con los bits enteros mapeados de esta manera:
texto alternativo http://www.mazeworks.com/mazegen/mazetut/tut5.gif
Para derribar una pared, establecer un borde o crear una ruta particular, todo lo que tenemos que hacer es voltear los bits en uno o dos elementos de la matriz.
¿Cómo uso banderas de bits en enteros de 16 bits para poder establecer cada uno de esos bits y verificar si están configurados?
Me gustaría hacerlo de una manera fácil de leer (es decir, Border.W, Border.E, Walls.N, etc.).
¿Cómo se hace esto generalmente en C ++? ¿Uso hexadecimal para representar cada uno (es decir, Walls.N = 0x02, Walls.E = 0x04, etc.)? ¿Debo usar una enumeración?
Consulte también ¿Cómo establece, borra y alterna un solo bit? .
Puede hacerlo con indicadores hexadecimales o enumeraciones como sugirió, pero la más legible / auto-documentada probablemente sea usar lo que se llama "bitfields" (para más detalles, Google para C++ bitfields
de C++ bitfields
).
Sí, una buena manera es usar un decimal hexadecimal para representar los patrones de los bits. Luego usa los operadores bit a bit para manipular sus entradas de 16 bits.
Por ejemplo:
if(x & 0x01){} // tests if bit 0 is set using bitwise AND
x ^= 0x02; // toggles bit 1 (0 based) using bitwise XOR
x |= 0x10; // sets bit 4 (0 based) using bitwise OR
Si quiere usar bitfields, esta es una manera fácil:
typedef struct MAZENODE
{
bool backtrack_north:1;
bool backtrack_south:1;
bool backtrack_east:1;
bool backtrack_west:1;
bool solution_north:1;
bool solution_south:1;
bool solution_east:1;
bool solution_west:1;
bool maze_north:1;
bool maze_south:1;
bool maze_east:1;
bool maze_west:1;
bool walls_north:1;
bool walls_south:1;
bool walls_east:1;
bool walls_west:1;
};
Entonces su código puede simplemente probar cada uno para verdadero o falso.
Usa constantes / enums hexadecimales y operaciones bit a bit si te importa qué bits particulares significan qué.
De lo contrario, use los campos de bits de C ++ (pero tenga en cuenta que el orden de los bits en el entero dependerá del compilador).
Para manipular conjuntos de bits, también puede usar ....
std::bitset<N>
std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );
No soy un gran fan de bitset. Simplemente es más tipeo en mi opinión. Y no oculta lo que estás haciendo de todos modos. Aún tienes que & && | bits. A menos que elija solo 1 bit. Eso puede funcionar para pequeños grupos de banderas. No es que tengamos que ocultar lo que estamos haciendo tampoco. Pero la intención de una clase es generalmente hacer algo más fácil para sus usuarios. No creo que esta clase lo logre.
Digamos, por ejemplo, que tiene un sistema de banderas con .. 64 banderas. Si quieres hacer la prueba ... No sé ... 39 de ellos en 1 declaración para ver si están todos encendidos ... usar bitfields es un gran dolor. Tienes que escribirlos a todos ... Curso. Asumo que solo se usa la funcionalidad bitfields y no los métodos mix and match. Lo mismo con bitset. A menos que me esté perdiendo algo con la clase ... lo cual es bastante posible ya que raramente lo uso ... No veo una forma en que puedas probar las 39 banderas a menos que digas el hoyo o recurras a "métodos estándar" (usando enum indica listas o algún valor definido para 39 bits y usa el operador de conjuntos de bits &&). Esto puede comenzar a complicarse dependiendo de su enfoque. Y lo sé .. 64 banderas suena como mucho. Y bueno. Es ... dependiendo de lo que estás haciendo. Personalmente hablando, la mayoría de los proyectos en los que participo dependen de los sistemas de banderas. Entonces en realidad ... 64 no es algo inaudito. Aunque 16 ~ 32 es mucho más común en mi experiencia. De hecho, estoy ayudando en un proyecto en el que un sistema de banderas tiene 640 bits. Básicamente es un sistema de privilegios. Por lo tanto, tiene algún sentido organizarlos todos juntos ... Sin embargo ... es cierto ... Me gustaría romper eso un poco ... pero ... eh ... estoy ayudando ... no creando.
Usar std::bitset