zfill funcion example bitwise array python bit-manipulation

funcion - ¿Es seguro desactivar un solo bit en indicadores con enteros de longitud variable de Python?



string to binary python (2)

En mi programa (escrito en Python 3.4) tengo una variable que contiene varias banderas, por ejemplo:

FLAG_ONE = 0b1 FLAG_TWO = 0b10 FLAG_THREE = 0b100 status = FLAG_ONE | FLAG_TWO | FLAG_THREE

Establecer otra bandera se puede hacer fácilmente con

status |= FLAG_FOUR

Pero, ¿y si explícitamente quiero borrar una bandera? Lo haría

status &= ~FLAG_THREE

¿Es este enfoque seguro? Como el tamaño de un entero en Python no está definido, ¿qué FLAG_THREE si el status y FLAG_THREE difieren en tamaño?

(El status debe ser un campo de bits porque necesito este valor para un protocolo de hardware).


Borrar una bandera trabaja con

status &= ~FLAG_THREE

porque Python trata esos valores negados como negativos:

>>> ~1L -2L >>> ~1 -2 >>> ~2 -3

Así, el & el operador puede actuar de manera adecuada y producir el resultado deseado, independientemente de la longitud de los operandos, por lo 0b11111111111111111111111111111111111111111111111111111111111 & ~1 funciona bien, aunque el operando de la izquierda es biffer que el de la derecha.

Sin embargo, en la otra dirección (RH más larga que LH), funciona, ya que tener un número excesivo de 1 bits no importa.


Deberías estar seguro usando ese enfoque, sí.

~ en Python se implementa simplemente como -(x+1) (consulte la fuente de CPython ) y los números negativos se tratan como si tuvieran cualquier número requerido de 1s que rellenen el inicio. De la Wiki de Python :

Por supuesto, Python no usa números de 8 bits. SE UTILIZÓ para usar, sin embargo, muchos bits eran nativos de su máquina, pero como no era portátil, recientemente se cambió a un número INFINITO de bits. Por lo tanto, el número -5 es tratado por operadores bit a bit como si estuviera escrito "... 1111111111111111111011".

En otras palabras, con bitwise y & está garantizado que esos 1s ajustarán la longitud de ~FLAG (un entero negativo) a la longitud del status . Por ejemplo:

100000010000 # status & ~10000 # ~FLAG

es tratado como

100000010000 & 111111101111 = 100000000000 # new status

Este comportamiento se describe en un comentario en la fuente here .