Um den Wert zu erhalten, der Ihrem C-Cast entspricht, nur bitweise und mit der entsprechenden Maske. zB wenn unsigned long
32 Bit ist:
>>> i = -6884376
>>> i & 0xffffffff
4288082920
oder wenn es 64 Bit ist:
>>> i & 0xffffffffffffffff
18446744073702667240
Beachten Sie jedoch, dass dies zwar den Wert ergibt, den Sie in C haben würden, es sich jedoch immer noch um einen vorzeichenbehafteten Wert handelt. Daher können nachfolgende Berechnungen zu einem negativen Ergebnis führen und Sie müssen die Maske weiterhin anwenden, um eine 32 oder 64 zu simulieren Bitberechnung.
Dies funktioniert, da Python zwar alle Zahlen als Vorzeichen und Größe speichert, die bitweisen Operationen jedoch so definiert sind, dass sie an den Zweierkomplementwerten arbeiten. C speichert ganze Zahlen in Zweierkomplement, jedoch mit einer festen Anzahl von Bits. Bitweise Python-Operatoren wirken auf Zweierkomplementwerte, aber als hätten sie eine unendliche Anzahl von Bits: Bei positiven Zahlen erstrecken sie sich mit Nullen nach links bis unendlich, negative Zahlen mit Einsen nach links. Der &
Operator ändert diese linke Einsenfolge in Nullen und lässt Ihnen nur die Bits übrig, die in den C-Wert passen würden.
Das Anzeigen der Werte in hexadezimaler Darstellung kann dies klarer machen (und ich habe die Zeichenfolge von f als Ausdruck umgeschrieben, um zu zeigen, dass wir an 32 oder 64 Bit interessiert sind):
>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'
Bei einem 32-Bit-Wert in C steigen positive Zahlen auf 2147483647 (0x7fffffff), und bei negativen Zahlen wird das oberste Bit von -1 (0xffffffff) auf -2147483648 (0x80000000) gesetzt. Für Werte, die vollständig in die Maske passen, können wir den Prozess in Python umkehren, indem wir eine kleinere Maske verwenden, um das Vorzeichenbit zu entfernen und dann das Vorzeichenbit zu subtrahieren:
>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376
Oder für die 64-Bit-Version:
>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376
Dieser inverse Prozess lässt den Wert unverändert, wenn das Vorzeichenbit 0 ist, aber offensichtlich ist es keine echte Inverse, denn wenn Sie mit einem Wert begonnen haben, der nicht in die Maskengröße passt, sind diese Bits weg.