Seite 1 von 1

long nach int wandeln

Verfasst: Freitag 1. September 2006, 08:18
von rayo
Hi

Ich habe den Wert 2158522173L und möchte diese aber in einem int speichern.

Code: Alles auswählen

i = 2158522173L
print int(i & 0xFFFFFFFF) # geht nicht weil das MSB das sign-Bit ist, also bleibt das ein long
print int(i & 0x7FFFFFFF) # gibt schon mal ein int und kein long mehr, jetzt muss einfach noch das MSB gesetzt werden
print int(i & 0x7FFFFFFF) | 0x80000000 # na toll und schon ists wieder ein long
Was ich komisch finde ist, dass eine OR-Verknüpfung mit dem sign-Bit nicht geht und direkt in einen Long gewandelt wird ... auf Bit-Ebene sollte es ja egal sein ob es signed oder unsigned ist.

Wie kann ich diese Zahl in einen Int wandeln (kann auch einen negativen Wert sein)? Das binäre Aussehen ist wichtig, nicht die Darstellung als pos/neg Zahl.

Gruss

Re: long nach int wandeln

Verfasst: Freitag 1. September 2006, 10:39
von BlackJack
rayo hat geschrieben:Ich habe den Wert 2158522173L und möchte diese aber in einem int speichern.
In einem Python `int` geht das nicht.

Code: Alles auswählen

i = 2158522173L
print int(i & 0xFFFFFFFF) # geht nicht weil das MSB das sign-Bit ist, also bleibt das ein long
print int(i & 0x7FFFFFFF) # gibt schon mal ein int und kein long mehr, jetzt muss einfach noch das MSB gesetzt werden
print int(i & 0x7FFFFFFF) | 0x80000000 # na toll und schon ists wieder ein long
Was ich komisch finde ist, dass eine OR-Verknüpfung mit dem sign-Bit nicht geht und direkt in einen Long gewandelt wird ... auf Bit-Ebene sollte es ja egal sein ob es signed oder unsigned ist.
Python `int`s haben kein "sign bit" an einer festen Stelle.
Wie kann ich diese Zahl in einen Int wandeln (kann auch einen negativen Wert sein)? Das binäre Aussehen ist wichtig, nicht die Darstellung als pos/neg Zahl.
Die Zahl ist zu gross für ein Python `int`. Wie ein Python `int` intern aussieht ist "unbekannt". Das könnte genauso wie ein `long` gespeichert sein, als Zeichenkette oder als Liste mit Primfaktorzerlegung.

Wenn Du Binärdaten haben möchtest:

Code: Alles auswählen

In [13]: struct.pack('I', 2158522173)
Out[13]: '=o\xa8\x80'

Verfasst: Freitag 1. September 2006, 10:52
von rayo
Hi

Ich brauche aber einen Integer, aber habs jetzt so gelöst:

Code: Alles auswählen

struct.unpack('i',struct.pack('I',zahl))[0]
2158522173L wird dann zu -2136445123 (int kein long).
So funktioniert es.

Gruss

Verfasst: Freitag 1. September 2006, 12:11
von BlackJack
Wozu brauchst Du denn ein unbedingt ein `int`? Das sollte nur an ganz wenigen Stellen wo eine drunterliegende C Bibliothek ein C `int` haben möchte wichtig sein.

Ohne `struct` geht's auch wenn Du das Zweierkomplement und die Negation "per Hand" machst:

Code: Alles auswählen

In [22]: int(-(2158522173 ^ 0xffffffff - 1))
Out[22]: -2136445123

Verfasst: Freitag 1. September 2006, 13:49
von rayo
Hi

Weil fcntl.ioctl den Befehl unbedingt als int haben will sonst gibts ne Exception mit "value too large to convert to int" oder sowas in der art.

Danke dann nehm ich das Zweierkomplement, wird ja schneller sein als struct.

Gruss