Luego de indagar en varios repositorios y sitios webs al concluir encontramos la respuesta que te enseñamos aquí.
Solución:
Funciona mejor si proporciona una máscara. De esa manera, especifica hasta dónde extender la señal.
>>> bin(-27 & 0b1111111111111111)
'0b1111111111100101'
O quizás de manera más general:
def bindigits(n, bits):
s = bin(n & int("1"*bits, 2))[2:]
return ("0:0>%s" % (bits)).format(s)
>>> print bindigits(-31337, 24)
111111111000010110010111
En teoría básica, el ancho real del número es una función del tamaño del almacenamiento. Si es un número de 32 bits, entonces un número negativo tiene un 1 en el MSB de un conjunto de 32. Si es un valor de 64 bits, entonces hay 64 bits para mostrar.
Pero en Python, la precisión de enteros está limitada solo a las restricciones de su hardware. En mi computadora, esto realmente funcionapero consume 9 GB de RAM solo para almacenar el valor de X. Algo más alto y obtengo un MemoryError. Si tuviera más RAM, podría almacenar números más grandes.
>>> x = 1 << (1 << 36)
Entonces, con eso en mente, ¿qué número binario representa -1
? Python es capaz de interpretar literalmente millones (e incluso miles de millones) de bits de precisión, como muestra el ejemplo anterior. En complemento a 2, el bit de signo se extiende completamente hacia la izquierda, pero en Python no hay un número predefinido de bits; hay tantos como necesites.
Pero luego te encuentras con la ambigüedad: ¿binario 1
representar 1
o -1
? Bueno, podría ser cualquiera. Lo hace 111
representar 7
o -1
? Nuevamente, podría ser cualquiera. También lo hace 111111111
representar 511
o -1
... bueno, ambos, dependiendo de tu precisión.
Python necesita una forma de representar estos números en binario para que no haya ambigüedad en su significado. los 0b
prefix simplemente dice "este número está en binario". Al igual que 0x
significa "este número está en hexadecimal". Entonces si digo 0b1111
, ¿cómo sé si el usuario quiere -1 o 15? Hay dos opciones:
Opción A:El bit de señal
Podría declarar que todos los números tienen signo y que el bit más a la izquierda es el bit de signo. Eso significa 0b1
es -1, mientras que 0b01
es 1. Eso también significa que 0b111
es también -1, mientras que 0b0111
es 7. Al final, esto es probablemente más confuso que útil, particularmente porque la mayor parte de la aritmética binaria va a estar sin firmar de todos modos, y es más probable que las personas cometan errores al marcar accidentalmente un número como negativo porque no incluyeron un bit de signo explícito.
Opción B:La señal de indicación
Con esta opción, los números binarios se representan sin signo y los números negativos tienen un "-" prefix, tal como lo hacen en decimal. Esto es (a) más consistente con el decimal, (b) más compatible con la forma en que es más probable que se usen los valores binarios. Pierde la capacidad de especificar un número negativo usando su representación en complemento a dos, pero recuerde que el complemento a dos es un implementación de almacenamiento detalle, no una indicación adecuada del valor subyacente en sí. No debería ser algo que el usuario tenga que entender.
Al final, la opción B tiene más sentido. Hay menos confusión y no se requiere que el usuario comprenda los detalles de almacenamiento.
Para interpretar correctamente una secuencia binaria como complemento a dos, se necesita una longitud asociada con la secuencia. Cuando trabaja con tipos de bajo nivel que se corresponden directamente con los registros de la CPU, existe una longitud implícita. Dado que los enteros de Python pueden tener una longitud arbitraria, realmente no existe un formato interno de complemento a dos. Dado que no hay una longitud asociada con un número, no hay forma de distinguir entre números positivos y negativos. Para eliminar la ambigüedad, bin() incluye un signo menos al formatear un número negativo.
El tipo entero de longitud arbitraria de Python en realidad usa un formato interno de magnitud de signo. Las operaciones lógicas (desplazamiento de bits, and, or, etc.) están diseñadas para imitar el formato de complemento a dos. Esto es típico de múltiples bibliotecas de precisión.
El complemento del significado de uno menos número es valor mod menos el valor positivo. Así que creo, la forma breve para el cumplido de -27 es
bin((1<<32) - 27) // 32 bit length '0b11111111111111111111111111100101'
bin((1<<16) - 27)
bin((1<<8) - 27) // 8 bit length '0b11100101'
Aquí puedes ver las reseñas y valoraciones de los lectores
Al final de todo puedes encontrar las acotaciones de otros sys admins, tú asimismo eres capaz insertar el tuyo si te apetece.