[pyar] Bitwise not..

Esteban Ordano esteban en ordano.com.ar
Jue Jun 17 09:26:05 ART 2010


2010/6/15 Roberto Alsina <ralsina en netmanagers.com.ar>
>
>
> Una curiosidad curiosa... el complemento, no depende del "largo" del tipo
> que
> estamos operando?
>
> Por ejemplo, si es un tipo byte:
>
> ~00000111 => 11111000
>
> Pero si es un tipo nibble (para no hacerlo con bytes y dobles bytes que es
> muy
> largo):
>
> ~0111 => 1000
>
> Y si después hacemos algo como
>
> 00001111 ^ (~00000111)  => 00001111 ^ 11110000 => 11111111
>
> mientras que
>
> 1111 ^ (~0111)  => 1111 ^ 1000 => 1111
>
> Que no es lo mismo...
>
> En python que los enteros no tienen representación fija, como hace? no sé,
> no
> entiendo del todo.


Si hacés ~0, si estás en una plataforma que use complemento al cero para el
storage, siempre vas a obtener el -1

Ojo que en esos ejemplos, el Xor no funciona así eh...

Y si después hacemos algo como

00001111 ^ (~00000111)  => 00001111 ^ 11110000 => 11111111


Ahí, estás haciendo 15 ^ ~7, que es 15 ^ -8 que dá 11110111, -9


 mientras que

1111 ^ (~0111)  => 1111 ^ 1000 => 1111


Ojo! Cuando python "castea" un número a una longitud mayor extiende el
último bit. Hace esto para preservar los números negativos si son negativos
o positivos. Creo que esta era tu duda de cómo trata Python a los números de
distinta precisión: extiende el bit de más a la izquierda hasta matchear la
longitud del otro operador.

Acá estás haciendo (no 15!!!) sino -1 ^ ~7 => -1 ^ -8 => 0111 = 7

Lo cual es el número desdeado (-1 ^ ~n es lo mismo que n).

Para hacer experimentos y no perderse en el camino:

def binary_repr(a):
    queue = []
    flag = 0
    if a < 0:
        flag = 1
        a = ~a
    while a:
        queue.append(str(a&1^flag))
        a >>= 1
    queue.reverse()
    return "(%d^n)"%flag+''.join(queue)


Yo suelo aprovecharme de que python tiene la misma sintáxis que para C++
cuando tengo que hacer bitwise masks y cosas locas por el estilo. La flag
esa antipythonica está porque el right shift en python funciona agregando el
último bit para preservar los números negativos.

Ya que estamos tiro una magia con bits que siempre me gustó:

while a:
    print a&-a
    a -= a&-a

Eso vá sacándolé bits a la variable a desde el menos significativo hasta el
más significativo, dejándote la representación en potencias de dos, y sin
necesidad de ir recorriendo los bits desde el 1 hasta encontrar un bit
"prendido"

Saludos,
Esteban
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20100617/dd7278da/attachment.html>


More information about the pyar mailing list