Seite 1 von 1

Umwandlung zwischen versch. Variablentypen

Verfasst: Montag 18. Januar 2010, 08:57
von Idefix_1024
ich versuche Hexadezimalzahlen umzuwandeln...

also z.B.

Code: Alles auswählen

int("F32F",16)
klappt wunderbar... nur wie bekomme ich python dazu den angegebenen Wert als eine signed integer Variable zu interpretieren?
Die Hexzahl entspricht einer Binärdarstellung von
F32F = 1111 0011 0010 1111

nun wäre ja das erste Bit ein Vorzeichenbit und damit ergibt sich für das gegebene Beispiel dann nicht 62255 sondern eben -29487... gibt es da eine elegante Möglichkeit der Unterscheidung bei der Umwandlung?

bin leider noch recht neu auf dem Thema Python...

Verfasst: Montag 18. Januar 2010, 10:11
von numerix
Indem du das so erhaltene dezimale Ergenis prüfst, ob es > 32767 ist und dann ggf. das Ergebnis von 32768 abziehst ...

Verfasst: Montag 18. Januar 2010, 10:19
von Idefix_1024
danke!

ich habe mich da ein wenig verwirren lassen...

mein Wert verwendet scheinbar das Einerkomplement (kannte ich bis dahin noch nicht oder nciht mehr)
dh alle negativen werte werden zusätzlich invertiert dargestellt... (die Null dann sogar doppelt)

mit der funktion

Code: Alles auswählen

def Hex2Int(hexstr):
    value = int(hexstr,16)
    length = len(hexstr)*4

    if (value >= 2**31) and (length == 32):
        value = (2**32-1) - value
        value = - value
    if (value >= 2**15) and (length == 16):
        value = (2**16-1) - value
        value = -value
    return value
klappt es jetzt scheinbar ganz gut!

FFE769E0 = -1611295

Verfasst: Montag 18. Januar 2010, 14:23
von HWK
Idefix_1024 hat geschrieben:mein Wert verwendet scheinbar das Einerkomplement (kannte ich bis dahin noch nicht oder nciht mehr)
dh alle negativen werte werden zusätzlich invertiert dargestellt... (die Null dann sogar doppelt)
:?:
Wohl eher das Zweierkomplement.
MfG
HWK

Verfasst: Montag 18. Januar 2010, 14:49
von cofi
HWK hat geschrieben:Wohl eher das Zweierkomplement.
Oder doch das Einerkomplement ;)

Verfasst: Montag 18. Januar 2010, 14:51
von Idefix_1024
beruhigend dass dieses Thema nicht nur mich verwirrt hat... auf jeden Fall sehen die Ergebnisse mit der geposteten Funktion inzwischen besser aus ;-)

danke!

Verfasst: Montag 18. Januar 2010, 19:02
von HWK
@cofi:
Idefix_1024 hat geschrieben:(die Null dann sogar doppelt)
Das klingt aber eher nach Zweierkomplement.
Wobei Hex2Int jedoch doch das Einerkomplement zurückliefert. Ob das wirklich so gewollt ist?
MfG
HWK

Verfasst: Dienstag 19. Januar 2010, 09:06
von Idefix_1024
ok... da habe ich wohl meine Verwirrung direkt ins Forum übertragen!

also:

Einerkomplement:
0100 = +4 und 1011 = -4
0111 = +7 und 1000 = -7
0000 = +0 und 1111 = -0
bei einer 1 im höchsten bit erfolgt bei der Umrechnung eine Invertierung aller nachfolgenden bits. Das höchste bit stellt nur das Vorzeichen bzw. die Unterscheidung zur Invertierung oder eben nicht dar.

Zweierkomplement:
0100 = +4 und 1100 = -4
0111 = +7 und 1000 = -8 wobei 1111 = -1 !
0000 = 0 es existiert nur diese eine Darstellung der Null !
Das höchste bit ist negativ zu interpretieren. Alle nachfolgenden bits werden normal ausgewertet. 1100 = -8 +4 = -4

damit dürfte das ganze etwas klarer sein... und hoffentlich richtig.

Was meine Funktion angeht, so liefert diese bei
FFFF = 0 und bei 0000 = 0!

Außerdem wird eine Hexzahl 8AAA = -30037
1000 1010 1010 1010 entspricht nach Einerkomplement
-0111 0101 0101 0101 = -30037

das Problem bei meiner Anwendung ist eher, dass ich erraten musste ob nun Einer- oder Zweierkomplement verwendet wird. Deshalb dann auch die totale Verwirrung irgendwann ;-)

inzwischen würde ich recht sicher behaupten, dass das Einerkomplement anzuwenden ist und meine Funktion dafür geeignet sein dürfte.

@HWK das Zweierkomplement kennt nur eine Null

alles Dinge mit denen ich mich lange nicht mehr beschäftigt habe... gibt es denn nun Python eigene Funktionen für diese Thematik? Wahrscheinlich wohl eher nicht...

Danke! Durch eure Antworten habe ich meine Gedanken ein wenig sortieren müssen, was wohl das Wichtigste zur Lösungsfindung war!

Ich hoffe das stimmt nun auch alles was ich hier poste!

Verfasst: Dienstag 19. Januar 2010, 10:09
von BlackJack
Alternative mit XOR:

Code: Alles auswählen

def hex2int(hex_string):
    bit_count = len(hex_string) * 4
    result = int(hex_string, 16)
    for i in [32, 16]:
        if result >= 2**(i - 1) and bit_count == i:
            result = - (result ^ (2**i - 1))
            break
    return result

Verfasst: Dienstag 19. Januar 2010, 13:22
von HWK
Interessehalber: Mit welcher Anwendung bzw. Prozessor, die das Einerkomplement zur Darstellung eines signed integers verwenden, arbeitest Du?
MfG
HWK

Verfasst: Dienstag 19. Januar 2010, 14:26
von Idefix_1024
es handelt sich um eine RS232 Kommunikation mit einem Controller... dieser sendet Messdaten in einem recht eigenwilligen Format.

Die Antwort beinhaltet einen Gleitkommawert und einen Integer-Wert. Der eigentliche Zahlenwert berechnet sich aus Multiplikation der beiden Werte.

Obwohl der Gleitkommawert bereits ohne Probleme ein Vorzeichen beinhaltet wird der Integer Wert bei negativen Werten vorzeichenbehaftet gesendet (das hatte ich nicht erwartet! Ist auch recht blöd... ist aber so).

Verfasst: Dienstag 19. Januar 2010, 18:31
von HWK
Naja, dann wird ja manches verständlicher.
MfG
HWK