Dezimalzahlen in Binärdarstellung - Meine Idee

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hallo,

ich weiss, ich weiss, man kann in Python Umwandlungen von Dezimalzahlen in Binärformate einfach erledigen in Form von:

Code: Alles auswählen

print int("1010", 2)
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
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Sorry, hier die letzte Zeile zur Ausgabe ein wenig "schöner":

Code: Alles auswählen

print "Binaerformat: %s" % (binarySequence[::-1], )

ne0h
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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 :wink:
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ups, nachdem ich den Thread nur bis

Code: Alles auswählen

print int("1010", 2)
gelesen habe, hab ichs natürlich in die falsche Richtung implementiert. :oops:
Zuletzt geändert von Leonidas am Sonntag 18. Mai 2008, 22:28, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
zerghase
User
Beiträge: 15
Registriert: Samstag 19. November 2005, 21:15
Wohnort: München

Leonidas hat geschrieben:))))))
Kanns sein dass du die falsche Sprache erwischt hast?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hallo Leonidas,

ehrlich gesagt, verstehe ich so gut wie nichts von Deinem Code. :wink:

Ist mir im Moment ein wenig zu.... "hoch".



ne0h
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

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
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

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
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Na ja, ich sehe es aber auch schon selber,

dass ich da einige Sachen drin habe, die doppelt sind.

ne0h
Benutzeravatar
sehbaer
User
Beiträge: 39
Registriert: Sonntag 30. März 2008, 17:26
Wohnort: Kölle

was bedeutet >>?
...es sind ganz bestimmt mehr Nullen als Einsen.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hallo sehbaer,

dabei handelt es sich um eine sogen. "Bitverschiebung".

Code: Alles auswählen

n >> 1
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
Benutzeravatar
sehbaer
User
Beiträge: 39
Registriert: Sonntag 30. März 2008, 17:26
Wohnort: Kölle

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...
...es sind ganz bestimmt mehr Nullen als Einsen.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

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:

Code: Alles auswählen

+ "01"[n % 2]

ne0h
Benutzeravatar
sehbaer
User
Beiträge: 39
Registriert: Sonntag 30. März 2008, 17:26
Wohnort: Kölle

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.
...es sind ganz bestimmt mehr Nullen als Einsen.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

"01"[n % 2] 
das entspricht:

Code: Alles auswählen

if n % 2 == 0:
    return '0'
else:
    return '1'
Es wird also n % 2 als Index für den String "01" benutzt.
Antworten