Zwei Komplement Binär in Python?

Integers in Python werden in zwei Komplementen gespeichert, richtig?

Obwohl:

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

Und:

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

Das ist ziemlich lahm. Wie bekomme ich Python, um mir die Nummern in REAL binären Bits zu geben, und ohne die 0b vor ihm? Damit:

 >>> x = 5 >>> bin(x) 0101 >>> y = -5 >>> bin(y) 1011 

10 Solutions collect form web for “Zwei Komplement Binär in Python?”

Nicht sicher, wie zu bekommen, was Sie wollen mit dem Standard-lib. Es gibt eine Handvoll Skripte und Pakete da draußen, die die Umwandlung für Sie tun wird.

Ich wollte nur das "Warum" beachten und warum es nicht lahm ist.

Bin () gibt keine binären Bits zurück. Es konvertiert die Zahl in eine binäre Zeichenfolge. Die führende '0b' erzählt dem Dolmetscher, dass es sich um eine Binärzahl handelt, wie es die Pythonsprache bedeutet. Auf diese Weise können Sie direkt mit Binärzahlen arbeiten

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

Das ist nicht lahm. das ist großartig.


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

Bin (x)

Konvertieren Sie eine Ganzzahl in eine binäre Zeichenfolge.

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

Integer- und Long-Integer-Literale werden durch die folgenden lexikalischen Definitionen beschrieben:

Bininteger :: = "0" ("b" | "B") bindigit +

Bindigit :: = "0" | "1"

Es funktioniert am besten, wenn du eine Maske verstellst. Auf diese Weise legen Sie fest, wie weit zu unterzeichnen ist.

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

Oder vielleicht allgemeiner:

 def bindigits(n, bits): s = bin(n & int("1"*bits, 2))[2:] return ("{0:0>%s}" % (bits)).format(s) >>> print bindigits(-31337, 24) 111111111000010110010111 

In der Grundtheorie ist die tatsächliche Breite der Zahl eine Funktion der Größe des Speichers. Wenn es eine 32-Bit-Nummer ist, dann hat eine negative Zahl eine 1 im MSB eines Satzes von 32. Wenn es ein 64-Bit-Wert ist, dann gibt es 64 Bits zum Anzeigen.

Aber in Python ist die Ganzzahl-Präzision nur auf die Einschränkungen Ihrer Hardware beschränkt. Auf meinem Computer, das funktioniert eigentlich , aber es verbraucht 9GB RAM nur um den Wert von x zu speichern. Alles höher und ich bekomme einen MemoryError. Wenn ich mehr RAM hätte, könnte ich größere Zahlen speichern.

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

Also, in diesem Sinne, welche Binärzahl bedeutet -1 ? Python ist gut in der Lage, buchstäblich Millionen (und sogar Milliarden) von Bits von Präzision zu interpretieren, wie das vorhergehende Beispiel zeigt. In 2's Komplement, das Vorzeichen Bit erstreckt sich den ganzen Weg nach links, aber in Python gibt es keine vordefinierte Anzahl von Bits; Es gibt so viele wie du brauchst

Aber dann laufen Sie in Zweideutigkeit: Ist Binär 1 1 oder -1 ? Nun, es könnte auch sein. Bedeutet 111 für 7 oder -1 ? Wieder könnte es auch sein. So macht 111111111 511 , oder -1 … gut, beide, je nach deiner Präzision.

Python braucht eine Möglichkeit, diese Zahlen im Binär darzustellen, so dass es keine Zweideutigkeit ihrer Bedeutung gibt. Das 0b Präfix sagt einfach "diese Nummer ist in binär". Genau wie 0x bedeutet "diese Nummer ist in Hex". Also, wenn ich sage 0b1111 , wie weiß ich, ob der Benutzer -1 oder 15 will? Es gibt zwei Möglichkeiten:

Option A: Das Zeichenbit
Sie können erklären, dass alle Zahlen signiert sind, und das linkste Bit ist das Zeichen-Bit. Das bedeutet, dass 0b1 -1 ist, während 0b01 ist. Das bedeutet auch, dass 0b111 auch -1 ist, während 0b0111 7 ist. Am Ende ist das wohl eher verwirrend als hilfreich, weil die meisten binären Arithmetiken sowieso nicht signiert werden, Und die Leute sind eher in Fehler zu versetzen, indem sie versehentlich eine Zahl als negativ markieren, weil sie kein explizites Zeichen-Bit enthielten.

Option B: Die Zeichenanzeige
Mit dieser Option sind Binärzahlen unsigned dargestellt, und negative Zahlen haben ein "-" Präfix, genau wie in Dezimal. Dies ist (a) im Einklang mit Dezimalzahl, (b) kompatibler mit der Art, wie binäre Werte am ehesten verwendet werden. Sie verlieren die Fähigkeit, eine negative Zahl mit der Zwei-Komplement-Darstellung zu spezifizieren, aber denken Sie daran, dass zwei Komplement ein Speicherimplementierungsdetail ist, nicht eine korrekte Angabe des zugrunde liegenden Wertes selbst. Es sollte nicht etwas sein, was der Benutzer verstehen muss.

Am Ende macht Option B am sinnvollsten. Es gibt weniger Verwirrung und der Benutzer ist nicht verpflichtet, die Speicherdetails zu verstehen.

Um eine binäre Sequenz als Zweierkomplement richtig zu interpretieren, muss eine Länge mit der Sequenz verbunden sein. Wenn Sie Low-Level-Typen arbeiten, die direkt den CPU-Registern entsprechen, gibt es eine implizite Länge. Da Python-Ganzzahlen eine beliebige Länge haben können, gibt es eigentlich kein internes Zwei-Komplement-Format. Da es keine Länge gibt, die mit einer Zahl verbunden ist, gibt es keine Möglichkeit, zwischen positiven und negativen Zahlen zu unterscheiden. Um die Mehrdeutigkeit zu entfernen, enthält bin () ein Minuszeichen bei der Formatierung einer negativen Zahl.

Pythons beliebige Länge Integer-Typ verwendet tatsächlich ein Zeichen-Größe interne Format. Die logischen Operationen (Bitverschiebung, und, etc.) sind so konzipiert, dass sie zwei Komplement-Format nachahmen. Dies ist typisch für mehrere Präzisionsbibliotheken.

Ich bin nicht ganz sicher, was du letztlich machen willst, aber du möchtest das Bitarray- Paket ansehen.

 def tobin(data, width): data_str = bin(data & (2**width-1))[2:].zfill(width) return data_str 

Verwenden Sie Scheiben, um unerwünschte '0b' loszuwerden.

bin(5)[2:] '101'

Oder wenn Sie Ziffern wollen,

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

oder auch

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

Für positive Zahlen verwenden Sie einfach:

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

Für negative Zahlen ist es ein wenig anders:

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

Als Ganzes ist es so, wie es aussehen soll:

 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) 
 tobin = lambda x, count=8: "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1))) 

z.B

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

Oder als klare Funktionen:

 # Returns bit y of x (10 base). ie # 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) 

(Angepasst von WJ Van de Laans Kommentar)

Eine Modifikation über die sehr hilfreiche Antwort von tylerl, die die Zeichenerweiterung für positive Zahlen sowie negative (keine Fehlerprüfung) bereitstellt.

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

Beispiel:

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

Ich hoffe, das löst dein Problem

 num = input("Enter number : ") bin_num=bin(num) binary = '0' + binary_num[2:] print binary 
  • Gibt es einen wahnsinnigen Trick, um die Teilbarkeit einer Zahl um 2 oder 3 zu überprüfen?
  • Bitweise XOR von Hex-Zahlen in Python
  • Von hexadezimal zu einem Komplement in Python
  • Zwei's Komplement in Python
  • Ist & schneller als% bei der Prüfung auf ungerade Zahlen?
  • Warum erlaubt Matplotlib's Slider nur einen Bereich von 0-7?
  • Lesen von niedrigstwertigen Bits in Python
  • Konvertieren von Bits in Bytes in Python
  • Wie umgekehrt man die signifikanten Bits einer Ganzzahl in Python?
  • Bit-weise Operation unary ~ (invertieren)
  • Unterschied zwischen ^ Operator in JS und Python
  • Python ist die beste Programmiersprache der Welt.