Estoy tratando de entender el código de una respuesta que recibí hoy :
a=0b01100001 b=0b01100010 bin((a ^ 0b11111111) & (b ^ 0b11111111))
Este es mi entendimiento:
bin
significa que el resultado será en forma binaria. a
es el proceso que pasa por la puerta. 0b
significa forma de base 2 ¿Alguien podría explicar el rest? Estoy confundido sobre 11111111
. &
es la puerta y (confuso por qué esto separa a los dos). ¿Y cómo cambiaría esto para que funcione para cualquier otra puerta, por ejemplo, XOR, NAND o …?
a ^ 0b11111111 #exclusive or's each bit in a with 1, inverting each bit >>> a=0b01100001 >>> bin(a ^ 0b11111111) '0b10011110' >>> bin((a ^ 0b11111111) & (b ^ 0b11111111)) '0b10011100'
Esto es diferente a usar el operador ~ ya que ~ devuelve un resultado binario negativo.
>>> bin(~a & ~b) '-0b1100100
La razón es que el operador ~ invierte todos los bits utilizados para representar el número, incluidos los 0 iniciales que normalmente no se muestran, lo que resulta en un resultado negativo del complemento de 2. Al utilizar ^ y la máscara binaria de 8 bits, solo se invierten los primeros 8 bits.
Comenzando con la respuesta original, que explica cómo se puede implementar una compuerta NOR usando AND y NOT:
Usted está pidiendo una operación Nwise bitwise:
r = not (a or b)
Además, puedes usar la ley de De Morgan, que dice que es equivalente a:
r = (not a) and (not b)
El cartel que traduce ese pseudocódigo en el Python que publicaste. Por alguna razón, usó ^ 0b11111111
para hacer un NO binario, en lugar de simplemente ~
, que es lo que habría elegido. Si cambiamos (a ^ 0b11111111)
al más simple ~
entonces obtenemos:
bin(~a & ~b)
Esa expresión es cómo se escribe “(no a) y (no b)” en Python. ~
significa NO y &
significa AND.
Un binario NO invierte todos los bits en un número. 0 se convierte en 1 y 1 se convierte en 0. La forma directa de hacerlo es con ~
. Una forma indirecta de voltear todos los bits en un número es XOR con todos los 1 bits. Eso tiene el mismo efecto, es solo más tiempo para escribir.
O en realidad, para ser más precisos, tiene casi el mismo efecto. ^ 0b11111111
voltea los primeros ocho bits del número porque hay ocho 1. Mientras que ~
voltea todos los bits. Si solo está interesado en los primeros 8 bits, puede agregar & 0b11111111
, que trunca los resultados a 8 bits:
>>> bin((~a & ~b) & 0b11111111) '0b10011100'
En mi opinión, esto es mejor que el misterioso ^ 0b11111111
.
El ^
es el operador XOR. XOR significa OR exclusivo. Uno de los operandos de ^
es una secuencia de unos. Básicamente, esto significa que todos los bits en el otro operando (es decir, a
o b
) se invertirán . Una vez que se realizan las dos operaciones XOR individuales, sus resultados son OR-ed.
Mirando fuera de los bits y las operaciones a nivel de bits, si lo ve desde el ámbito de las operaciones lógicas, el código es esencialmente haciendo (! A ) ^ (! B)
que según la ley de DeMorgan es idénticamente igual a ! (A v B)
! (A v B)
que es la operación NOR.