2009-02-13 34 views
10

Según el sitio web this, deseo representar un laberinto con una matriz bidimensional de números enteros de 16 bits.¿Cómo se utilizan las marcas bit a bit en C++?

Cada número entero de 16 bits tiene que contener la siguiente información:

He aquí una manera de hacerlo (esto es de ninguna manera la única manera): una rejilla de 12x16 laberinto puede representarse como una matriz m [ 16] [12] de enteros de 16 bits. Cada elemento de la matriz haría contiene toda la información para una sola celda correspondiente en la red, con los bits de número entero mapeadas como esto:

alt text http://www.mazeworks.com/mazegen/mazetut/tut5.gif

para derribar una pared, establecer una frontera, o cree un camino particular, todo lo que tenemos que hacer es voltear 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?


Véase también How do you set, clear, and toggle a single bit?.

Respuesta

1

Puede hacerlo con indicadores hexadecimales o enums como sugirió, pero el más legible/autodocumentado probablemente sea usar lo que se llama "bitfields" (para más detalles, Google para C++ bitfields).

3

Utilice las constantes/enums hexadecimales y las operaciones bit a bit si le importa qué bits particulares significan qué.

De lo contrario, use los campos de bits C++ (pero tenga en cuenta que el orden de los bits en el entero dependerá del compilador).

1

Sí, una buena manera es usar un decimal hexadecimal para representar los patrones de 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 
2

Learn sus operadores turísticos, bit a bit: &, |, ^, y!.

En la parte superior de una gran cantidad de archivos C/C++ he visto banderas definidas en hexadecimal para enmascarar cada bit.

#define ONE 0x0001 

para ver si un bit está activado, Y con 1. Para encenderlo, usted o con 1. Para alternar como un interruptor, XOR con 1.

9

Si desee utilizar campos de bits, entonces esto 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; 
}; 

a continuación, el código sólo se puede probar cada uno de verdadero o falso.

+0

lamentablemente esto no es portátil ya que el orden de los bits es específico del compilador. –

+0

Además, no estoy seguro si bool es un tipo soportado para bitfields, sería más portable si se usa unsigned. –

+0

sí bool es compatible con bitfields, pero está en lo cierto, el orden de ellos depende totalmente del compilador y generalmente está asociado con endianess – KPexEA

2

para manipular conjuntos de bits, también se puede usar ....

std::bitset<N>

std::bitset<4*4> bits; 
bits[ 10 ] = false; 
bits.set(10); 
bits.flip(); 
assert(!bits.test(10)); 
0

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. Todavía tiene 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. Estoy asumiendo que usa solo funcionalidad bitfields y no mezcla y combina métodos. 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 los conjuntos de bits & & operador). 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.