justin meiners
Recientemente me he encontrado con varios ejemplos de “banderas” en C y C++, y no entiendo muy bien cómo funcionan. Después de mirar un poco de código fuente, noté que a menudo los valores de las banderas se definen en hexadecimal, como los siguientes:
FLAG1 = 0x00000001,
FLAG2 = 0x00000010,
Mi intuición sugiere que estos valores se están combinando. ¿Funcionan las banderas combinando todos los valores de las banderas en un int? Si hubiera usado ambos como FLAG1 | FLAG2
seria el resultado 0x00000011
?
¿Necesito crear enumeraciones con compensaciones de bits o puedo usar números enteros ascendentes como:
FLAG1 = 1;
FLAG2 = 2;
Debe compensar los bits; de lo contrario, no hay forma de extraer las banderas individuales. Si tuviera banderas correspondientes a 1, 2, 3 y 4, y un valor combinado de 5, ¿cómo podría saber si era 2 y 3 o 1 y 4?
También puedes hacerlo de esta manera, por ejemplo:
enum {
FIRST = 1 << 0, // same as 1
SECOND = 1 << 1, // same as 2, binary 10
THIRD = 1 << 2, // same as 4, binary 100
FOURTH = 1 << 3 // same as 8, binary 1000
};
Luego combinas banderas así:
int flags = FIRST | THIRD | FOURTH;
Y los extraes así:
if (flags & THIRD) { ...
marca byers
Su primer método no es usar los bits de la manera más eficiente. En el primer ejemplo, está utilizando notación hexadecimal y es equivalente a:
TEXTUREFLAGS_POINTSAMPLE = 1,
TEXTUREFLAGS_TRILINEAR = 16,
En el segundo método, parece que solo está aumentando en uno cada vez. Esto no funcionará cuando combine banderas, porque el valor combinado podría ser el mismo que otra bandera (por ejemplo, 1 | 2 == 3).
Deberías usar estos valores en su lugar:
0x00000001 // == 1
0x00000002 // == 2
0x00000004 // == 4
0x00000008 // == 8
0x00000010 // == 16
0x00000020 // == 32
0x00000040 // == 64
etc...
Estas son las potencias de dos y se pueden combinar usando bit a bit o de cualquier forma sin dar colisiones.
-
Ok, pero no funcionará si solo hago uno para dar me gusta a 20, ¿verdad? Todavía tengo que escalonar el hexadecimal para que no se sobrescriban, ¿verdad? O no entiendo cómo funciona.
–Justin Meiners
4 sep 2010 a las 19:30
-
@ user425756, si no usa potencias de dos, no puede notar la diferencia entre el 1 y el 2 configurados, o el 3 configurado.
–Paul Tomblin
4 sep 2010 a las 19:33
-
Sí, eso es lo que estaba pensando.
–Justin Meiners
4 sep 2010 a las 19:39
Indicadores como este son valores binarios, por lo que puede combinar 1, 2, 4, 8, 16, 32, 64, 128 en un solo byte, o más potencias de 2 hasta 2^31 en un int. Debido a que son valores binarios, puedes “o” juntos, así que si “o” juntos 1,2,4 terminas con 7, por ejemplo. Y puede extraer el bit que desea usando “y”, por lo que si tiene un int con algunas banderas o juntas, y desea ver si el bit “4” está configurado, puede decir if (flag & 4)
y será cierto si se establece el bit “4”.
-
Gracias eso tiene más sentido.
–Justin Meiners
4 sep 2010 a las 19:33
Piense en las banderas como una matriz de 32 bits (booleanos)
Para activar uno de estos bits en usted O con 1
Una vez que supere la diferencia entre OR/AND digital y OR/AND lógico, todo encajará. ¡Entonces apreciarás la notación hexadecimal!