Seite 1 von 1
Umwandlung binär <-> dezimal
Verfasst: Montag 28. September 2009, 12:22
von snafu
Mit Version 2.6 hat Python ein Builtin erhalten, das Dezimalzahlen in Binärzahlen umwandeln kann. Ich fand allerdings die Ausgabe etwas komisch:
Code: Alles auswählen
In [1]: bin(267)
Out[1]: '0b100001011'
In [2]: bin(-267)
Out[2]: '-0b100001011'
Deshalb hab ich mir etwas Kosmetik geschrieben:
Code: Alles auswählen
def binary(number):
return int(''.join(bin(number).split('0b')))
Ergebnis:
Code: Alles auswählen
In [3]: import binary
In [4]: binary.binary(267)
Out[4]: 100001011
In [5]: binary.binary(-267)
Out[5]: -100001011
Ich bin allerdings kein Mathematiker. Vielleicht ist die Pythonausgabe aus irgendwelchen Gründen besser. Würd mich dann interessieren, warum das so ist...
Eine umgekehrte Funktion hab ich nicht in Python gefunden und sie daher selbst implementiert:
Code: Alles auswählen
def bin2dec(binary):
return sum(int(state) * 2**e
for (e, state) in enumerate(reversed(str(binary))))
Die Zahl wird also zunächst in eine iterierbare Sequenz (ein String) umgewandelt und anschließend umgekehrt, damit der Index als Exponent genutzt werden kann. Wenn jemandem eine bessere Lösung einfällt, dann her damit. ;P
Verfasst: Montag 28. September 2009, 12:40
von jbs
Ich denke mal, dass man bei ``bin`` die Binärdarstellung wollte und ``100001011`` ist ja ein int. Naja, keine Ahnung

Verfasst: Montag 28. September 2009, 12:54
von snafu
Ich find's nicht gerade einleuchtend, dass `eval()` die Rückumwandlung macht, aber nagut, dann gibt's das ja schon.
Achso, bei `hex()` gibt's das z.B. auch. Kannte ich alles noch nicht.
Verfasst: Montag 28. September 2009, 13:38
von numerix
snafu hat geschrieben:Ich find's nicht gerade einleuchtend, dass `eval()` die Rückumwandlung macht
eval() braucht es dafür auch nicht:
Verfasst: Montag 28. September 2009, 13:41
von jbs
Warum erkennt ``int`` das ``0b`` nicht, bzw. warum muss man ``base=2`` mit angeben?
Verfasst: Montag 28. September 2009, 14:07
von snafu
jbs hat geschrieben:warum muss man ``base=2`` mit angeben?
Also mir fällts gerade wie Äpfel aus den Augen.
Re: Umwandlung binär <-> dezimal
Verfasst: Montag 28. September 2009, 14:41
von EyDu
snafu hat geschrieben:Ich bin allerdings kein Mathematiker. Vielleicht ist die Pythonausgabe aus irgendwelchen Gründen besser. Würd mich dann interessieren, warum das so ist...
Der Grund ist recht einfach: In einem Integer werden Werte gespeichert (zu welcher Basis auch immer). Wenn du einen Integer zum Beispiel mittels "print" ausgibst, dann wird dieser im Dezimalsystem dargestellt. Du wandelst die binäre Darstellung hingegen nur so um dass sie im Dezimalsystem binär aussieht. Das Problem wird hier deutlich:
Code: Alles auswählen
>>> a = 15
>>> b = 7
>>> print a + b
22
>>> print binary(a) + binary(b)
1222
Bei der letzten Ausgabe würde man natürlich 10110 erwarten und nicht 1222.
Verfasst: Montag 28. September 2009, 14:55
von snafu
`int(bin(a) + bin(b), 2)` gibt allerdings auch nen ValueError. Man bräuchte vielleicht einen eigenen Datentyp für binäre Zahlen.
Nur auf dem Weg gehts:
Verfasst: Montag 28. September 2009, 15:08
von EyDu
Richtig, weil es Strings sind und es sich um eine DARSTELLUNG handelt. Binäre Zahlen brauchen keinen eigenen Datentyp, das sie keine eigenen Typen sind. Sie sind nur die Darstellung einer Zahl!
Es ist vollkommen egal ob du
42 zur Basis 10 oder
101010 zur Basis 2 schreibst.
Es ist zweimal der selbe Wert, nur mit verschiedenen Basen.
Verfasst: Montag 28. September 2009, 15:11
von numerix
snafu hat geschrieben:Man bräuchte vielleicht einen eigenen Datentyp für binäre Zahlen.
Ich hab seinerzeit mal so etwas zur Übung gemacht:
http://www.python-forum.de/topic-13891.html
Verfasst: Montag 28. September 2009, 23:06
von snafu
Ich dachte halt an etwas in der Art `b"100011010"`, ähnlich wie man das bei Unicode mit dem `u` kennt. Ich finde das jedenfalls mit den Strings nicht gerade elegant gelöst. Aber vielleicht lieg ich da auch falsch. Die Mehrheit scheint ja eher dagegen zu sein.
Verfasst: Montag 28. September 2009, 23:28
von Leonidas
snafu hat geschrieben:Ich dachte halt an etwas in der Art `b"100011010"`, ähnlich wie man das bei Unicode mit dem `u` kennt.
Sowas gibts in Python 2.6 und Python 3
snafu hat geschrieben:Die Mehrheit scheint ja eher dagegen zu sein.
Ja, finde ich auch eher unnütz. Letztens bin ich drüber gestolpert, dass GCC 0b...-Literale unterstützt um dann kurz darauf auf die Nase zu fliegen weil das Indentation-Tool damit nicht zurecht kommt (sind wie sich rausstellt nonstandard) und damit sind die auch Prompt wieder aus meinem Code verschwunden. In Python fände ich es praktischer wenn man Hexadezimal und Oktalliterale entfernen würde und das parsen dann von einem Builtin wie ``int()`` erledigen lässt. Im Gegensatz zu C braucht man Hexadezimalzahlen in Python ganz selten und Oktalzahlen nahezu nie.
Verfasst: Dienstag 29. September 2009, 07:03
von BlackJack
@jbs: Das ``base=2`` braucht man, weil der Default-Wert von dem Argument 10 ist. Und ich würde mich beschweren, wenn `int()` dann aus der Eingabe "0b11" etwas anderes als eine Ausnahme machen würde, oder schlimmer noch: wenn aus der Eingabe "09" ein `ValueError` und keine 9 werden würde. Denn so etwas wäre mir beim Parsen von Datumsangaben sicher schonmal um die Ohren geflogen.
Wenn man als `base` die 0 angibt, dann parst `int()` eine Zeichenkette so wie der Compiler das im Quelltext machen würde.
Verfasst: Dienstag 29. September 2009, 09:11
von jbs
Verstanden. Danke.
Verfasst: Dienstag 29. September 2009, 09:26
von snafu
Leonidas hat geschrieben:snafu hat geschrieben:Ich dachte halt an etwas in der Art `b"100011010"`, ähnlich wie man das bei Unicode mit dem `u` kennt.
Sowas gibts in Python 2.6 und Python 3

Also unter Python 2.6 hat mir `bin()` den eingangs genannten String zurückgegeben. Oder hab ich dich jetzt falsch verstanden?
Verfasst: Dienstag 29. September 2009, 11:46
von Leonidas
snafu hat geschrieben:Leonidas hat geschrieben:snafu hat geschrieben:Ich dachte halt an etwas in der Art `b"100011010"`, ähnlich wie man das bei Unicode mit dem `u` kennt.
Sowas gibts in Python 2.6 und Python 3

Also unter Python 2.6 hat mir `bin()` den eingangs genannten String zurückgegeben. Oder hab ich dich jetzt falsch verstanden?
Damit habe ich scherzweise gemeint dass Python 3 und Python 2.6 (mit ``from __future__ import unicode_literals``) Byte-Literale haben, die eben das angesprochene Format haben
