operación bit a bit unaria ~ (invertir)
Estoy un poco confundido con el ~
operador. El código va a continuación:
a = 1
~a #-2
b = 15
~b #-16
¿Cómo ~
funciona?
Pensé ~a
que sería algo como:
0001 = a
1110 = ~a
¿por qué no?
Tienes toda la razón. Es un artefacto de la representación de enteros en complemento a dos .
En 16 bits, 1 se representa como 0000 0000 0000 0001
. Invertido, obtienes 1111 1111 1111 1110
, que es -2. De manera similar, 15 es 0000 0000 0000 1111
. Invertido, obtienes 1111 1111 1111 0000
, que es -16.
En general,~n = -n - 1
El operador '~' se define como: "La inversión bit a bit de x se define como -(x+1). Sólo se aplica a números enteros". Documento Python - 5.5
La parte importante de esta oración es que está relacionada con los 'números integrales' (también llamados números enteros). Su ejemplo representa un número de 4 bits.
'0001' = 1
El rango de enteros de un número de 4 bits es '-8...0...7'. Por otro lado, podría utilizar 'enteros sin signo', que no incluyan números negativos y el rango para su número de 4 bits sería '0...15'.
Dado que Python opera con números enteros, se espera el comportamiento que usted describió. Los números enteros se representan mediante complemento a dos. En el caso de un número de 4 bits, esto se parece a lo siguiente.
7 = '0111'
0 = '0000'
-1 = '1111'
-8 = '1000'
Python usa 32 bits para la representación de enteros en caso de que tenga un sistema operativo de 32 bits. Puedes comprobar el número entero más grande con:
sys.maxint # (2^31)-1 for my system
En caso de que desee que se le devuelva un entero sin signo para su número de 4 bits, debe enmascararlo.
'0001' = a # unsigned '1' / integer '1'
'1110' = ~a # unsigned '14' / integer -2
(~a & 0xF) # returns 14
Si desea obtener un rango de números de 8 bits sin signo (0..255), simplemente use:
(~a & 0xFF) # returns 254