Domanda

Sto lavorando a un programma in cui memorizzo alcuni dati in un numero intero e li elaboro a bit. Ad esempio, potrei ricevere il numero 48, che elaborerò bit per bit. In generale l'endianità degli interi dipende dalla rappresentazione automatica degli interi, ma Python fa qualcosa per garantire che gli ints siano sempre little-endian? O devo controllare l'endianness come farei in C e quindi scrivere un codice separato per i due casi?

Lo chiedo perché il mio codice viene eseguito su una macchina Sun e, sebbene quello su cui è in esecuzione ora utilizza processori Intel, in futuro potrei dover passare a una macchina con processori Sun, che so essere big-endian.

È stato utile?

Soluzione

int di Python ha la stessa endianness del processore su cui gira. Il modulo struct ti consente di convertire i BLOB di byte in in (e viceversa e anche alcuni altri tipi di dati) in modo nativo, little-endian o big-endian, a seconda del stringa di formato tu scegli: avvia il formato con @ o nessun carattere di endianness per usare endianness nativo (e dimensioni native - tutto il resto usa dimensioni standard)," ~ 'for native,' < ' per little-endian, ">" o '!' per big-endian.

Questo è byte per byte, non bit per bit; non so esattamente cosa intendi per elaborazione bit per bit in questo contesto, ma presumo che possa essere sistemato in modo simile.

Per un veloce "bulk" elaborazione in casi semplici, si consideri anche il modulo array - il fromstring e tostring possono operare rapidamente su un gran numero di byte, e il metodo byteswap può farti ottenere gli " altro " endianness (da nativo a non nativo o viceversa), sempre rapidamente e per un gran numero di elementi (l'intero array).

Altri suggerimenti

Se devi elaborare i tuoi dati 'bit per bit', allora bitstring potrebbe esserti di aiuto. Può anche gestire l'endianità tra le piattaforme (almeno sull'ultima build del trunk - che verrà rilasciata nei prossimi giorni).

Il struct module è il miglior metodo standard di occuparsi di endianness tra piattaforme. Ad esempio, questo comprime e scompatta gli interi 1, 2, 3 in due "short" e uno "long" (2 e 4 byte sulla maggior parte delle piattaforme) usando l'endianness nativo:

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)

Per verificare l'endianità della piattaforma a livello di codice è possibile utilizzare

>>> import sys
>>> sys.byteorder

che restituirà " big " o " little " .

Controlla quando?

Quando si eseguono operazioni bit per bit, int in avrà la stessa endianess degli ints inseriti. Non è necessario verificarlo. È necessario preoccuparsene solo quando si converte in / da sequenze di byte, in entrambe le lingue, afaik.

In Python si utilizza il modulo struct per questo, più comunemente struct.pack () e struct.unpack ().

Il frammento seguente ti dirà se il tuo sistema predefinito è little endian (altrimenti è big-endian)

import struct
little_endian = (struct.unpack('<I', struct.pack('=I', 1))[0] == 1)

Nota, tuttavia, ciò non influirà sul comportamento degli operatori bit a bit: 1 < < 1 è uguale a 2 indipendentemente dall'endianness predefinita del tuo sistema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top