In sostanza, il problema è quello di firmare estendere da 32 bit a ... un numero infinito di bit, perché Python ha numeri interi arbitrariamente grandi. Normalmente, l'estensione del segno viene eseguita automaticamente dalle istruzioni della CPU durante il casting, quindi è interessante che sia più difficile in Python di quanto non lo sarebbe, ad esempio C.
Giocando in giro, ho trovato qualcosa di simile alla funzione di BreizhGatch, ma che non richiede una dichiarazione condizionale. n & 0x80000000
estrae il bit di segno a 32 bit; quindi, lo -
mantiene la stessa rappresentazione a 32 bit ma firma-estende; infine, i bit di segno esteso sono impostati su n
.
def toSigned32(n):
n = n & 0xffffffff
return n | (-(n & 0x80000000))
Bit Twiddling Hacks suggerisce un'altra soluzione che forse risulterà più in generale. n^0x80000000
capta il bit di segno a 32 bit; quindi - 0x80000000
firmerà-estenderà il bit opposto. Un altro modo di pensarci è che inizialmente i numeri negativi sono al di sopra dei numeri positivi (separati da 0x80000000
); lo ^
scambia le loro posizioni; poi i turni -
numeri negativi al di sotto 0.
def toSigned32(n):
n = n & 0xffffffff
return (n^0x80000000) - 0x80000000
Questo non è accurato: tutti i calcoli che si adattano alla parola della macchina vengono eseguiti in quel livello. Ad esempio, ~ 1 == -2. Quindi sto cercando un modo per forzare il risultato in tipo int (che non è ciò che int() fa, apparentemente). –
~ 1 == -2 in Python su * tutti * i sistemi. Se questo non è il caso sul sistema nativo, quindi un'implementazione Python deve emularlo. (Vedi http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy.) L'unica volta che la dimensione della parola nativa può perdere in Python è quando la dimensione di int è maggiore di 32-bit , il che significa che si effettua la transizione da Int a molto più tardi. –
Non è possibile forzare Python a convertire un valore long in un int quando il valore non si adatta a un int; non puoi scrivere codice Python come se fossi in C.Se si desidera convertire il valore int intatto a 32 bit da 0xFFFFFFFF al numero intero a 32 bit con complemento firmato e rappresentato dalla stessa stringa di bit, allora ho fornito il codice. Altrimenti, non sono sicuro di cosa stai cercando di fare. –