Cita:
Empezado por orfeo
porque estas preguntando si una variable Dword es true
|
No, no estoy preguntando eso. El operador
and en esa expresión no es el operador lógico entre variables booleanas sino un operador de bits.
La cuestión es más o menos así (ejemplifico con un byte pero es similar para un dword). En la representación interna de la máquina, un byte consta de ocho bits, cada bit puede tomar el valor 0 ó 1. Cuando aplicas el operador
and a dos bytes el efecto es el de aplicar un
and lógico bit por bit según la tabla
Código:
+-----+-----+-----+
| and | 0 | 1 |
+-----+-----+-----+
| 0 | 0 | 0 |
+-----+-----+-----+
| 1 | 0 | 1 |
+-----+-----+-----+
Así, si tienes los bytes
Código:
b1 = 00110100 (52 decimal)
b2 = 10101110 (174 decimal)
la operación
and te da:
Código:
b1 = 00110100
b2 = 10101110
b1 and b2 = 00100100 (36 decimal)
Análogamente, el operador
or aplicado a números enteros significa la aplicación de un
or lógico bit por bit según la tabla:
Código:
+-----+-----+-----+
| or | 0 | 1 |
+-----+-----+-----+
| 0 | 0 | 1 |
+-----+-----+-----+
| 1 | 1 | 1 |
+-----+-----+-----+
Con b1 y b2 como arriba tendrías:
Código:
b1 = 00110100
b2 = 10101110
b1 or b2 = 10111110 (190 decimal)
Ahora bien, lo que comunmente se conoce como una bandera (flag) es una potencia de 2. La representación en bits de una potencia de 2 consta exclusivamente de ceros con un único 1 en el lugar n-ésimo contando desde cero de derecha a izquierda, donde n es la potencia. Así, por ejemplo,
Código:
2^0 = 00000001 (1 decimal)
2^1 = 00000010 (2 decimal)
2^2 = 00000100 (4 decimal)
2^3 = 00001000 (8 decimal
2^4 = 00010000 (16 decimal)
2^5 = 00100000 (32 decimal)
2^6 = 01000000 (64 decimal)
2^7 = 10000000 (128 decimal)
Si combinas dos banderas mediante el operador
or (que en este caso es lo mismo que sumar), aplicando el
or lógico bit por bit, lo que obtienes es un byte con dos 1 en las posiciones de cada bandera. Por ejemplo:
2^2
or 2^6 = 0
1000
100
es decir, un arreglo de ocho bits con dos de ellos prendidos (= a 1). Esta es la forma en que las banderas las puedes combinar en un sólo número.
La pregunta entoces es, ¿cómo saber en general qué banderas (bits) en un byte dado están prendidas?
Si volvemos al operador
and nota que la única manera en que dos bits den igual a 1 es cuando ambos son 1. Como una bandera (potencia de 2) sólo tiene un bit 1 y todos los demás 0, al hacer el
and con otro byte se apagan todos los bits excepto, posiblemente, el que está en la misma posición que el 1 en la potencia de 2. Luego entonces todo depende exclusivamente del valor del bit en esa posición (has
aislado el bit). Si es 1 entonces el resultado será un byte con un único 1 (en la misma posición que el de la potencia de 2) y si es cero será un byte con sólo 0s, es decir, igual al número 0.
Por ejemplo, si b=0010
1011 y la bandera es f=2^3=0000
1000, entonces
b
and f = 0000
1000 <> 0 (decimal)
Pero si la bandera es f=2^5=0010
0000 entonces
b
and f = 0000
0000 = 0 (decimal)
En resumen, al hacer el
and de un byte cualquiera y una bandera (potencia de 2) el resultado sólo puede ser
- 0 si el byte tiene prendido el bit en la posición de la potencia de 2
- 1 si el byte tiene apagado el bit en la posición de la potencia de 2
y de aquí la comparación con 0 para saber si está prendida o apagada.
// Saludos