Enteros en Python se almacenan en complemento a dos, ¿correcto?

Aunque:

>>> x = 5
>>> bin(x)
0b101

Y:

>>> x = -5
>>> bin(x)
-0b101

Que es bastante cojo. ¿Cómo puedo lograr que python me dan los números en binario REAL bits, y sin 0b enfrente de ella? Así:

>>> x = 5
>>> bin(x)
0101
>>> y = -5
>>> bin(y)
1011
InformationsquelleAutor Thor Correia | 2012-10-18

12 Comentarios

  1. 3

    No sabe cómo conseguir lo que deseas usando el estándar lib. Hay un puñado de secuencias de comandos y los paquetes que va a hacer la conversión para usted.

    Sólo quería nota el «por qué» , y ¿por qué no lo cojo.

    bin() no devuelve bits binarios. convierte el número a una cadena binaria. el líder ‘0’ indica al intérprete que usted está tratando con un número binario , como por el lenguaje python definición. de esta manera usted directamente puede trabajar con números binarios, como este

    >>> 0b01
    1
    >>> 0b10
    2
    >>> 0b11
    3
    >>> 0b01 + 0b10
    3

    que no es cojo. eso es genial.


    http://docs.python.org/library/functions.html#bin

    bin(x)

    Convertir un número entero a una cadena binaria.

    http://docs.python.org/reference/lexical_analysis.html#integers

    Entero y entero largo literales son descritos por las siguientes definiciones léxicas:

    bininteger ::= «0» («b» | «B») bindigit+

    bindigit ::= «0» | «1»

  2. 64

    Funciona mejor si usted proporciona una máscara. Que manera de especificar en qué medida a firmar extender.

    >>> bin(-27 & 0b1111111111111111)
    '0b1111111111100101'

    O tal vez 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

    Básicas de la teoría, el ancho real de la serie es una función del tamaño de la de almacenamiento. Si es un número de 32 bits, a continuación, 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, número entero de precisión está limitada únicamente a las limitaciones de su hardware. En mi equipo, este realmente funciona, pero consume 9 gb de memoria RAM para almacenar el valor de x. Nada más y me da un MemoryError. Si tuviera más memoria RAM, yo podría almacenar números más grandes.

    >>> x = 1 << (1 << 36)

    Así que con eso en mente, ¿qué número binario que representa -1? Python es bien capaz de interpretar literalmente, millones de personas (e incluso miles de millones) de los bits de precisión, como el ejemplo anterior se muestra. En complemento a 2, el bit de signo se extiende todo el camino a la izquierda, pero en Python no hay ningún pre-define el número de bits; hay tantas como necesites.

    Pero, a continuación, ejecutar en la ambigüedad: ¿binario 1 representan 1, o -1? Bueno, podría ser cualquiera. ¿111 Representan 7 o -1? De nuevo, podría ser cualquiera. Lo hace 111111111 representan 511, o -1… bueno, ambos, dependiendo de su precisión.

    Python necesita una forma de representar estos números en binario para que no exista ambigüedad de su significado. El 0b prefijo dice «este número en binario». Como 0x significa «este número en hexadecimal». Lo que si me dicen 0b1111, ¿cómo puedo saber si el usuario quiere -1 o 15? Hay dos opciones:

    Opción a: El bit de signo

    Usted podría declarar que todos los números están firmados, y más a la izquierda de bit es el bit de signo. Eso significa que 0b1 es de -1, mientras que 0b01 es 1. Eso también significa que 0b111 también es -1, mientras que 0b0111 es 7. En la final, este es probablemente más confuso que particularmente útil porque la mayoría de la aritmética binaria va a ser sin signo de todos modos, y la gente es más probable que se ejecute en errores por el accidente de marcado de un número negativo, ya que no incluyen explícitamente bit de signo.

    Opción B: El signo indicación

    Con esta opción, los binarios se representan los números sin signo, y los números negativos tienen un «-» prefijo, igual que en decimal. Este es el (a) más consistente con decimales, (b) más compatible con la forma en que los valores binarios son más probable que va a ser utilizado. Se pierde la capacidad de especificar un número negativo el uso de su complemento a dos de la representación, pero recuerda que el complemento a dos es un implementación de almacenamiento de detalle, no una correcta indicación del valor subyacente en sí. No debería ser algo que el usuario tiene que entender.

    Al final, la Opción B tiene más sentido. Hay menos confusión y el usuario no está obligado a entender los detalles del almacenamiento.

    • +1, con el propósito de generar una representación en forma impresa, este es el método más sencillo. (Tenga en cuenta, sin embargo, que el resultado real de -27 & 0b111111111 es un número positivo en la memoria!)
    • es sólo un número positivo si el bit más significativo es 0. Cuántos bits hay? Bueno, eso es lo que usted decida con su máscara. Si usted decide que usted está limitado a 16 bits, para los propósitos de este el 16 de bits especifica la señal. Simple y sencillo.
    • A la derecha, pero mi punto es simplemente que memoria, el bit más significativo en el valor que resulta de -27 & 0b11111111 es un cero. (En general, el resultado de & siempre será positivo si uno de los operandos es positivo, ya que un valor positivo se entiende precedido por un infinita cadena de ceros.)
    • bin(-12 & int('0b' + '1' * 16, 2)) para los perezosos.
    • Cualquier persona puede elaborar en la «Opción a»? Una vez que hube de hecho esta es mi caso, ¿cómo convertir un negativo número binario a decimal?
    • gracias. el uso de este método,puedo imprimir cualquier bit para restringir el número negativo del complemento a dos. supongamos que usted quiere obtener el número binario de -9, sin embargo, si especifica los bits máxima es de 5. puede realizar bin(-9 & 0b11111). y obtener 0b10111.

  3. 14

    Para interpretar correctamente una secuencia binaria como complemento a dos, se necesita una longitud asociada con la secuencia. Cuando se trabaja bajo nivel de los tipos que se corresponden directamente con los registros de la CPU, hay implícita una longitud. Dado que Python enteros puede tener una longitud arbitraria, en realidad no hay una interna complemento a dos de formato. Puesto que no hay una longitud asociada con un número, no hay manera de distinguir entre números positivos y negativos. Para eliminar la ambigüedad, bin() incluye un signo menos cuando se formatea un número negativo.

    Python longitud arbitraria de tipo entero en realidad utiliza un signo-magnitud formato interno. Las operaciones lógicas (bit de desplazamiento, y, o, etc.) están diseñados para imitar el formato de complemento a dos. Esto es típico de múltiples precisión de las bibliotecas.

  4. 3
    tobin = lambda x, count=8: "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))

    por ejemplo,

    tobin(5)      # =>  '00000101'
    tobin(5, 4)   # =>      '0101'
    tobin(-5, 4)  # =>      '1011'

    O como funciones claras:

    # Returns bit y of x (10 base).  i.e. 
    # bit 2 of 5 is 1
    # bit 1 of 5 is 0
    # bit 0 of 5 is 1
    def getBit(y, x):
        return str((x>>y)&1)
    
    # Returns the first `count` bits of base 10 integer `x`
    def tobin(x, count=8):
        shift = range(count-1, -1, -1)
        bits = map(lambda y: getBit(y, x), shift)
        return "".join(bits)

    (Adaptado de W. J. Van de Laan del comentario)

  5. 1

    Utilizar rebanadas de deshacerse de los indeseables ‘0’.

    bin(5)[2:]
    ‘101’

    o si desea dígitos,

    tuple ( bin(5)[2:] )
    (‘1’, ‘0’, ‘1’)

    o incluso

    map( int, tuple( bin(5)[2:] ) )
    [1, 0, 1]

  6. 1

    Para números positivos, sólo tiene que utilizar:

    bin(x)[2:].zfill(4)

    Para los números negativos, es un poco diferente:

    bin((eval("0b"+str(int(bin(x)[3:].zfill(4).replace("0","2").replace("1","0").replace("2","1"))))+eval("0b1")))[2:].zfill(4)

    Como un guión completo, esta es la forma en que debe buscar:

    def binary(number):
        if number < 0:
            return bin((eval("0b"+str(int(bin(number)[3:].zfill(4).replace("0","2").replace("1","0").replace("2","1"))))+eval("0b1")))[2:].zfill(4)
        return bin(number)[2:].zfill(4)      
    x=input()
    print binary(x)
    • Esto no produce el resultado solicitado para los números negativos. El resultado debe ser 1011, no 101.
    • gracias, he solucionado el problema
    • Bien, ahora se la da de malo resultados de los otros números. binary(-4) debería ser algo así como 1100 o 11111100, pero esto da 11, que es totalmente equivocado.
    • he corregido el código, y no el binario de -4 0011?
    • No en complemento a dos.
    • oh, mi error, ahora el programa utiliza dos cumplido

  7. 1

    Una modificación en tylerl muy útil la respuesta que proporciona la señal de extensión para números positivos como los negativos (sin comprobación de errores).

    def to2sCompStr(num, bitWidth):
        num &= (2 << bitWidth-1)-1 # mask
        formatStr = '{:0'+str(bitWidth)+'b}'
        ret =  formatStr.format(int(num))
        return ret

    Ejemplo:

    In [11]: to2sCompStr(-24, 18)
    Out[11]: '111111111111101000'
    
    In [12]: to2sCompStr(24, 18)
    Out[12]: '000000000000011000'
  8. 1

    No hay necesidad, lo que ya es. Es sólo la elección de python para representar de una manera diferente. Si de iniciar la impresión de cada picar por separado, va a mostrar sus verdaderos colores.

    checkNIB = '{0:04b}'.format
    checkBYT = lambda x: '-'.join( map( checkNIB, [ (x>>4)&0xf, x&0xf] ) ) 
    checkBTS = lambda x: '-'.join( [ checkBYT( ( x>>(shift*8) )&0xff ) for shift in reversed( range(4) ) if ( x>>(shift*8) )&0xff ] )
    
    
    print( checkBTS(-0x0002) )

    De salida es simple:

    >>>1111-1111-1111-1111-1111-1111-1111-1110  

    Ahora vuelve a la representación original cuando se quiere mostrar un dos complementar de un mordisco, pero aún es posible si la divides en dos mitades de picar y así. Sólo tiene en mente que el mejor resultado es negativo en hexadecimal y binario entero interpretaciones simples números no tanto, también con hex puede configurar el tamaño en bytes.

  9. 0

    Aquí es un poco más legible versión de Tylerl respuesta, por ejemplo, digamos que usted quiere -2 en su 8-bits de la representación negativa de «complemento a dos» :

    bin(-2 & (2**8-1))

    2**8 soportes para el noveno bit (256), reste 1 y tiene todos los anteriores conjunto de bits a uno (255)

    de 8 y 16 bits máscaras, usted puede reemplazar la (2**8-1) por 0xff, o 0xffff. La versión hexadecimal se vuelve menos readalbe después de ese punto.

    Si esto no es claro, aquí es una función regular de la misma:

    def twosComplement (value, bitLength) :
        return bin(value & (2**bitLength - 1))
  10. -1

    Espero que esto resuelve el problema`

    num = input("Enter number : ")
    bin_num=bin(num)
    binary = '0' + binary_num[2:]
    print binary

Dejar respuesta

Please enter your comment!
Please enter your name here