Comprender el operador AND a nivel de bit

He estado leyendo acerca de operadores de bits en Objective-C en el libro de Kochan, “Progtwigción en Objective-C”.

Estoy MUY confundido acerca de esta parte, aunque realmente he entendido todo lo demás que se me presentó hasta ahora.

Aquí hay una cita del libro:

El operador Bitwise AND

El ANDing bit a bit se usa frecuentemente para operaciones de enmascaramiento. Es decir, este operador se puede usar fácilmente para establecer bits específicos de un elemento de datos en 0. Por ejemplo, el enunciado

w3 = w1 & 3; 

asigna a w3 el valor de w1 ANDed en modo bit con la constante 3. Esto tiene el mismo efecto de establecer todos los bits en w, distintos de los dos bits más a la derecha en 0 y preservar los dos bits más a la derecha de w1.

Al igual que con todos los operadores aritméticos binarios en C, los operadores de bits binarios también se pueden usar como operadores de asignación al agregar un signo igual. La statement

 word &= 15; 

por lo tanto, realiza la misma función que la siguiente:

 word = word & 15; 

Además, tiene el efecto de establecer todos menos los cuatro bits de la palabra más a la derecha en 0. Cuando se usan constantes para realizar operaciones en modo bit, generalmente es más conveniente express las constantes en notación octal o hexadecimal.

OK, entonces eso es lo que trato de entender. Ahora, estoy extremadamente confundido con casi todo este concepto y solo estoy buscando una pequeña aclaración si alguien está dispuesto a ayudarme con eso.

Cuando el libro hace referencia a “establecer todos los bits” ahora, todos los bits … ¿Qué es exactamente un poco? ¿No es solo un 0 o 1 en la segunda base, en otras palabras, binario?

Si es así, ¿por qué, en el primer ejemplo, todos los bits, excepto el “más a la derecha 2”, son 0? ¿Es 2 porque es 3 – 1, tomando 3 de nuestra constante?

¡Gracias!

Los números se pueden express en binario de esta manera:

 3 = 000011 5 = 000101 10 = 001010 

… etc. Voy a suponer que estás familiarizado con el binario.

Bitwise AND significa tomar dos números, alinearlos uno encima del otro y crear un nuevo número que tiene un 1 donde ambos números tienen un 1 (todo lo demás es 0).

Por ejemplo:

  3 => 00011 & 5 => 00101 ------ ------- 1 00001 

Bitwise OR significa tomar dos números, alinearlos uno encima del otro y crear un nuevo número que tenga un 1 donde cualquier número tiene un 1 (todo lo demás es 0).

Por ejemplo:

  3 => 00011 | 5 => 00101 ------ ------- 7 00111 

Bitwise XOR (OR exclusivo) significa tomar dos números, alinearlos uno encima del otro y crear un nuevo número que tenga un 1 donde cualquier número tiene un 1 Y el otro número tiene un 0 (todo lo demás es 0).

Por ejemplo:

  3 => 00011 ^ 5 => 00101 ------ ------- 6 00110 

Bitwise NOR (no OR) significa tomar el bitio O de dos números, y luego invertir todo (donde había un 0, ahora hay un 1, donde había un 1, ahora hay un 0).

Bitwise NAND (Not AND) significa tomar el AND bit a bit de dos números, y luego invertir todo (donde había un 0, ahora hay un 1, donde había un 1, ahora hay un 0).

Continuando: ¿por qué la word &= 15 establece todos menos los 4 bits más a la derecha en 0? Deberías ser capaz de resolverlo ahora …

  n => abcdefghjikl & 15 => 000000001111 ------ -------------- ? 00000000jikl 

( 0 AND a = 0 , 0 AND b = 0 , … j AND 1 = j , i AND 1 = i , …)

¿Cómo es esto útil? En muchos idiomas, usamos cosas llamadas “máscaras de bits”. Una máscara de bits es esencialmente un número que representa un grupo completo de números más pequeños combinados. Podemos combinar números usando OR, y separarlos usando AND. Por ejemplo:

 int MagicMap = 1; int MagicWand = 2; int MagicHat = 4; 

Si solo tengo el mapa y el sombrero, puedo expresslo como myInventoryBitmask = (MagicMap | MagicHat) y el resultado es mi máscara de bits. Si no tengo nada, mi máscara de bits es 0. Si quiero ver si tengo mi varita mágica, puedo:

 int hasWand = (myInventoryBitmask & MagicWand); if (hasWand > 0) { printf("I have a wand\n"); } else { printf("I don't have a wand\n"); } 

¿Consíguelo?

EDITAR: más cosas

También te encontrarás con el operador “bitshift”: << y >>. Esto solo significa “cambiar todo lo que queda n bits” o “cambiar todo en n bits”.

En otras palabras:

1 << 3 = 0001 << 3 = 0001000 = 8

Y:

8 >> 2 = 01000 >> 2 = 010 = 2

“Bit” es la abreviatura de “dígito binario”. Y sí, es un 0 o 1. Casi siempre hay 8 en un byte, y están escritos como números decimales, con el dígito más significativo a la izquierda y el menos significativo a la derecha.

En su ejemplo, w1 & 3 enmascaran todo menos los dos dígitos menos significativos (más a la derecha) porque 3, en binario, es 00000011. (2 + 1) La operación AND devuelve 0 si el bit AND es 0, por lo que todo menos el último dos bits son automáticamente 0.

 w1 = ????...??ab 3 = 0000...0011 -------------------- & = 0000...00ab 

0 y cualquier bit N = 0

1 y cualquier bit N = N

Por lo tanto, cualquier bit bitded anded con 3 tiene todos sus bits excepto los dos últimos establecidos en 0. Los dos últimos bits, ayb en este caso, se conservan.

@cHao y todos: ¡No! Los bits no son números. ¡No son cero ni uno!

Bueno, 0 y 1 son interpretaciones posibles y válidas. Cero y uno es la interpretación típica.

Pero un poco es solo una cosa, representa una alternativa simple. Dice “es” o “no es”. No dice nada sobre la cosa, el “eso”, sí mismo. No dice, que cosa es.

En la mayoría de los casos esto no te molestará. Puede tomarlos por números (o partes, dígitos, números) como usted (o la combinación de lenguajes de progtwigción, CPU y otro hardware, que usted conoce como “típico”), y probablemente nunca tenga problemas con ellos.

Pero no hay un problema principal si cambia el significado de “0” y “1”. Ok, si haces esto mientras progtwigs el ensamblador, lo encontrarás un poco problemático ya que algunos mnemotécnicos harán otra lógica, luego te dicen con sus nombres, los números serán negados y esas cosas.

Eche un vistazo a http://webdocs.cs.ualberta.ca/~amaral/courses/329/webslides/Topic2-DeMorganLaws/sld017.htm si lo desea.

Saludos

Intereting Posts