Python Dezimal und Hexadezimal berechnen?

2 Antworten

Du musst eine Schleife aufsetzen deren Rest immer kleiner wird und nur solange läuft wie der Rest noch größer als 16 ist (DEZ ->Hex Wandlung)
Dürft ihr keine "Mathe-Bibliothek" verwenden. So etwas gibt es natürlich schon von anderen gelöst und zur Verfügung gestellt.


DoktorDave 
Beitragsersteller
 14.03.2021, 12:26

Doch, Mathe-Bibliotheken dürfen wir verwenden. Die einzige Einschränkung bezieht sich auf die eingebauten Funktionen. Echt? Gibt es da schon Beispiele? Als ich dazu recherchiert habe, habe ich leider nichts gefunden.

Letztlich muß DU nur den Algorithmus abbilden.

Machen wir erstmal Hexadezimal zu Dezimal, nehmen wir eine Zahl wie:

2FFA

Die Stellen entsprechen von rechts nach links 16^0, 16^1, 16^2 usw. .

Meine Zahl ergibt sich also aus 2*16^3+F*16^2+F*16^1+A*16^0. Merke, daß der größte Exponent um 1 kleiner als die Länge des Strings ist.

Nun habe ich generell unterschiedliche Möglichkeiten vorzugehen. Schauen wir zunächst auf ein Teilproblem, ich muß die einzelnen Stellen in ihre dezimalen Gegenstücke konvertieren, das kann ich in Python ganz bequem mit einem Dictionary lösen:

hex2dec={'0':0,'1':1,'a':10,'f':15}

Exemplarisch, natürlich muß Du alle 15 Hexziffern im Dict haben. Das bequeme dabei ist, daß ich mit dem in-Operator gleich auch prüfen kann, ob die Ziffenr im Wertebereich liegen.

------

Wir können also nun die Länge des Strings bestimmen, um den größten Exponenten zu bestimmen und dann einfach in einer Schleife die oben gezeigte Rechnung ausführen, indem wir die Ziffer konvertieren, mit dem 16^x multiplizieren und alles aufsummieren.

Wir können das aber auch machen, ohne die Länge zu kennen:

>>> hex='23FF9A1'
>>> for digit in reversed(hex):
...    print(digit)
...
1
A
9
F
F
3
2

Wir laufen die Ziffern in ungekehrter Reihenfolge ab und zählen stattdessen den Exponenten hoch.

e=0
result=0
for digit in reversed(hexstring):
    result+=mydict[digit]*math.pow(16,e)
    e+=1

Kommen wir zu einer weiteren Methode, bei der ich die Länge nicht kennen muß und sogar ohne Potenzieren auskommen, ich demonstriere das nochmal an der Beispielzahl:

2*16^3+F*16^2+F*16^1+A*16^0

Wenn ich nun Mit 0 Anfange mit 16 multipliziere und 2 addiere, mit 16 Multipliziere und F addiere, mit 16 multipliziere usw. usf. . Dann erhalte ich

(((2*16)+F)*16+F)*16)+A

Was genau der Darstellung mit Potenzen nach Ausmultiplizieren entspricht.

Der Vorteil dieses Ansatzes ist, daß er mit einfacher Multiplikation und Addition auskommt.

Algorithmisch sieht das dann etwa so aus:

result=0
for digit in hexstring:
   result*=16
   result+=hex2dec(digit)

Hier ohne Gültigkeitsprüfung und unter der Annahme, daß hex2dec eine Hexziffer zu einem Dezimalwert umwandelt (Umsetzung wie gezeigt über Dictionary).

------

Die Umkehrung der letzten Variante ist dann das wiederholte dividieren durch 16, bequem in diesem Zusammenhang ist

>>> divmod(1240,16)
(77, 8)

Die Ganzzahldivision mit Rest.

>>> val=8712389
>>> while val>0:
...    val,r=divmod(val,16)
...    print(r)
...
5
12
0
15
4
8
>>> hex(8712389)
'0x84f0c5'

Wie Du siehst erzeugt die Schleife 5, C, 0, F, 5 ,8

Ich erzeuge vorzugsweise wieder ein Dictionary, diesmal mit int zu Dezimalzifern:

d={1:'1',2:'2',...,10:'A',...,15:'F'}

Und baue mir aus den Zeichen dann den String, indem ich vorne den konvertierten Dezimalwert anhänge.