Seite 1 von 2
Dezimalzahlen in Binärdarstellung - Meine Idee
Verfasst: Sonntag 18. Mai 2008, 21:25
von ne0h
Hallo,
ich weiss, ich weiss, man kann in Python Umwandlungen von Dezimalzahlen in Binärformate einfach erledigen in Form von:
Da ich mich aber gerne mit den Details befasse und dies erstmal selber schreiben wollte (vor allem auch als Übung für mich), habe ich mich dran gesetzt und dieser Code ist dabei heraus gekommen:
(Ich habe bewusst erstmal keine try-except Blöcke, es geht mir nur um die reine Berechnung)
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print "\n** Dieses Programm wandelt Dezimalzahlen in Binaerzahlen um. **\n"
decimal = int(raw_input("Dezimalzahl eingeben:"))
tempResult = decimal
binarySequence = ""
while tempResult != 0:
tempResult = decimal / 2
binaryBit = decimal % 2
decimal = tempResult
binaryBitAsStr = str(binaryBit)
binarySequence += binaryBitAsStr
print binarySequence[::-1]
Das ist natürlich kein Meisterstück, aber ich wollte mir selber die Umrechnung herleiten und dabei hatte ich ganz zum Schluss das Problem, dass ich nicht wusste, wie ich meinen String "binarySequence" umdrehe, sprich: von hinten nach vorne ausgebe.
Zuvor habe ich es mit einer Liste versucht (mit der reverse() - Funktion) aber die Ausgabe danach kam mir nicht so entgegen. Dann bin ich auf die idee gekommen, mich des "Slicings" zu bedienen und damit hat es dann auch ganz gut geklappt, was in der letzten Zeile steht.
Nun zur Kritik: Was ist in Euren Augen nicht effektiv? Was würdet Ihr anders machen? Was habe ich falsch/schlecht gemacht?
Gruß
ne0h
Verfasst: Sonntag 18. Mai 2008, 21:29
von ne0h
Sorry, hier die letzte Zeile zur Ausgabe ein wenig "schöner":
ne0h
Verfasst: Sonntag 18. Mai 2008, 21:57
von sma
Ich würde es vielleicht so machen:
Code: Alles auswählen
def d2b(n):
d = ""
while n:
d += "01"[n & 1]
n >>= 1
return d[::-1]
Oder doch lieber rekursiv, da das noch ein bisschen eleganter ist:
Code: Alles auswählen
def d2b(n):
return d2b(n / 2) + "01"[n % 2] if n else ""
Stefan
Verfasst: Sonntag 18. Mai 2008, 22:01
von EyDu
Jetzt könnte man natürlich anmerken, dass "n" gar keine Dezimalzahl ist, aber ich meine mich da an einen Thread erinnern zu können, in dem dieses diskutiert wurde

Verfasst: Sonntag 18. Mai 2008, 22:05
von sma
Mein "n" muss wie dein "decimal" ein `int` sein. Python kennt streng genommen keine Dezimalzahl, kann aber eine Ganzzahl (eben ein `int`) in Dezimalform darstellen - oder in Binärform. Und das ist doch, was du wolltest - eine Ganzzahl in Binärform darstellen. Ich liefere dir dazu zwei Funktionen.
Stefan
Verfasst: Sonntag 18. Mai 2008, 22:12
von ne0h
Hi,
sma, ich denke Du meinst mit Deiner letzten Antwort "EyDu" und nicht mich.
Aber Danke schonmal für Deine Ideen, ich werde mir das mal durch den Kopf gehen lassen und meinen Code dann versuchen anzupassen.
Gruß
ne0h
Verfasst: Sonntag 18. Mai 2008, 22:19
von Leonidas
Ups, nachdem ich den Thread nur bis
gelesen habe, hab ichs natürlich in die falsche Richtung
implementiert.

Verfasst: Sonntag 18. Mai 2008, 22:27
von zerghase
Leonidas hat geschrieben:))))))
Kanns sein dass du die falsche Sprache erwischt hast?
Verfasst: Montag 19. Mai 2008, 00:58
von Leonidas
zerghase hat geschrieben:Leonidas hat geschrieben:))))))
Kanns sein dass du die falsche Sprache erwischt hast?

Ich weiß ja nicht, das ist ja nur Python mit Klammersyntax

(Im Ernst, auch wenn die Einrückung nicht ganz optimal ist, was daran liegt, dass ich nicht so viel Erfahung damit habe, so ist das Scheme-Programm vergleichsweise lesbar, außerdem ist die Schittmenge zwischen Scheme und Python erstaunlich groß).
Ich habe es wie sma in d2b rekursiv gelöst, allerdings traditionell mit Arthmetischen Shifts. Interessanterweise unterscheidet Scheme (wie die OpenVMS-Makrosprache) nicht zwischen Links und Rechts-Shift (habe grad die Wikipedia um diese feststellng bereichert, endlich mal Zeit sich dort anzumelden).
Konverter in beide Richtungen in Klammer-Python 
(der sogar einen Fehler im Lexer triggert - Uuups).
Verfasst: Montag 19. Mai 2008, 16:20
von ne0h
Hallo Leonidas,
ehrlich gesagt, verstehe ich so gut wie nichts von Deinem Code.
Ist mir im Moment ein wenig zu.... "hoch".
ne0h
Verfasst: Montag 19. Mai 2008, 17:02
von Leonidas
Wenn du dir die erste Fassung von d2b ansiehst dann ist es gar nicht mal so schwer.
Eine 1:1-Übersetzung würde so aussehen:
Code: Alles auswählen
def d2b(n):
shifted = n >> 1
if shifted == 0:
return [n % 2]
else:
return [n % 2] + d2b(shifted)
Natürlich könnte man überlegen, das Modulo vorzuziehen.
Die zweite Fassung ist auch ganz ähnlich, in Python ist es dank überladenen Operatoren nur nötig den Typ zu ändern:
Code: Alles auswählen
def d2b(n):
shifted = n >> 1
if shifted == 0:
return str(n % 2)
else:
return str(n % 2) + d2b(shifted)
Verfasst: Montag 19. Mai 2008, 17:46
von ne0h
Also diese rekursiven Aufrufe will ich jetzt gleich mal angehen. Ich hab die Umkehrfunktion von Binär in Dezimal noch dazu geschrieben und werde beide Funktionen jetzt umarbeiten und dabei auch versuchen verstehen.
Aber, auch auf die Gefahr hin, dass ich grad völlig neben mir stehe:
Was genau ist das für eine Sprache, in der Deine verlinkten Beispiele sind? Bzw.: Was hat das Ganze mit den von Dir gerade geschriebenen Beispielen zu tun?
Stehe da grade auf dem Schlauch.
Gruß
ne0h
Verfasst: Montag 19. Mai 2008, 17:51
von ne0h
Der Vollständigkeit halber und weil mich auch Eure Meinung interessiert, hier meine Umkehrfunktion, also von Binär in Dezimal (auch nur die reine Funktionalität, ohne try-except und ohne besondere Formatierungen):
Code: Alles auswählen
def binToDez():
get = raw_input("Binaerfolge eingeben: ")
binStrList = []
binIntList = []
count = 0
for i in get:
if i == "0" or i == "1":
binStrList.append(i)
count += 1
if count != len(get):
print "Reihenfolge ist falsch"
binStrList = []
else:
print "Reihenfolge ist Ok!"
for i in binStrList:
binIntList.append(int(i))
reversedSequence = binIntList[:]
reversedSequence.reverse()
sum = 0
exp = 0
for i in reversedSequence:
temp = i * (2 ** exp)
sum += temp
exp += 1
print "Dezimalzahl: %s" % (sum, )
Wäre das, abgesehen von der Tatsache, dass es eben rekursive Aufrufe dafür gibt, eine halbwegs akzeptable Implementierung?
ne0h
Verfasst: Montag 19. Mai 2008, 18:11
von ne0h
Na ja, ich sehe es aber auch schon selber,
dass ich da einige Sachen drin habe, die doppelt sind.
ne0h
>>
Verfasst: Montag 19. Mai 2008, 18:50
von sehbaer
was bedeutet >>?
Verfasst: Montag 19. Mai 2008, 19:11
von ne0h
Hallo sehbaer,
dabei handelt es sich um eine sogen. "Bitverschiebung".
bedeutet in diesem Fall, dass der Inhalt von "n" um eine Bitstelle nach rechts verschoben wird.
So zumindest kenne ich diese Schreibweise.
Man korrigiere mich bitte, falls ich es falsch erklärt habe.
ne0h
bitshift, Bitverschiebung
Verfasst: Montag 19. Mai 2008, 19:45
von sehbaer
Danke! Hatte ich schon ein wenig vermutet und nun auch gefunden:
http://docs.python.org/ref/shifting.html
Nach solchen Zeichen ist leider immer ganz übel zu suchen...
Verfasst: Montag 19. Mai 2008, 20:22
von ne0h
Hm... könnte mir Jemand diese Lösung von "sma" Schritt für Schritt erläutern?
Code: Alles auswählen
def d2b(n):
return d2b(n / 2) + "01"[n % 2] if n else ""
Ich komme damit nicht ganz zurecht, auch wenn es einwandfrei läuft. Irgendwie fehlt mir da das Verständnis, warum ich auf das "return" diese Addition durchführe bzw. warum überhaupt eine Addition und dann mit diesem Ausdruck:
ne0h
concat
Verfasst: Montag 19. Mai 2008, 20:46
von sehbaer
Ich versuche mich da mal: Das ist eher eine Concatenation als eine Addition. Da wird eine Zeichenkette zusammengetüdelt. Aus der Zeichenkette "01" wird abhängig davon, ob n gerade oder ungerade ist eine "0" oder "1" "herausindiziert" und solange aneindandergetüdelt, bis n = 0 (False) ist. Ich finde Rekursionen immer so schlimm zu beschreiben und hoffe ich habe mich da einigermaßen verständlich ausgedrückt.
Verfasst: Montag 19. Mai 2008, 20:46
von audax
das entspricht:
Es wird also n % 2 als Index für den String "01" benutzt.