Differenze tra le versioni di "Conversione Big-Endian/Little-Endian"
Riga 7: | Riga 7: | ||
Se ad esempio abbiamo il valore decimale 1234567, la memorizzazione nella seguente forma: | Se ad esempio abbiamo il valore decimale 1234567, la memorizzazione nella seguente forma: | ||
12 D6 87 | 12 D6 87 | ||
− | è di tipo ''Big-Endian'', mentre una | + | è di tipo ''Big-Endian'', mentre una memorizzazione nella forma: |
87 D6 12 | 87 D6 12 | ||
è, invece, di tipo ''Little-Endian. | è, invece, di tipo ''Little-Endian. |
Versione delle 02:41, 21 gen 2014
Big-Endian e Little-Endian sono due differenti modalità per memorizzare dati di dimensione superiore al semplice byte.
La differenza tra i due sistemi è data dall'ordine, con il quale i byte costituenti il dato vengono memorizzati:
- Big-Endian è il tipo di memorizzazione che inizia dal byte più significativo e termina con il byte meno significativo;
- Little-Endian è il tipo di memorizzazione che inizia dal byte meno significativo e termina con il byte più significativo.
Se ad esempio abbiamo il valore decimale 1234567, la memorizzazione nella seguente forma:
12 D6 87
è di tipo Big-Endian, mentre una memorizzazione nella forma:
87 D6 12
è, invece, di tipo Little-Endian.
In taluni casi particolari, pertanto, possiamo riscontrare che alcuni valori vengono scritti per la memorizzazione in modalità Little-Endian, e che, pertanto, per comprenderne il reale significato/valore, devono essere convertiti in forma Big-Endian. Possiamo, per converso, avere valori che, memorizzati inizialmente nel formato esadecimale della forma Big-Endian, debbano essere convertiti in forma Little-Endian, affinché altri pogrammi possano comprendere il loro reale significato e restituire quindi il vero valore.
Indice
Conversione Big-Endian/Little-Endian di un valore a 16bit
La formula astratta per ottenere la conversione Big-Endian/Little-Endian di un valore a 16bit (= 2 byte, ossia di tipo Short) può essere la seguente (anche se le modalità sono molteplici per ottenere la conversione):
((valore >> 8) & 0x00FF) | ((valore << 8) & 0xFF00)
che in Gambas potremo tradurre quella formula, utilizzando le funzioni di scorrimento dei bit a destra ed a sinistra, in sintassi così:
Hex((Shr(&valore, 8) And &FF) Or (Shl(&valore, 8) And &FF00&), 4) As String
V'è da sottolineare che il il valore &FF00& necessita assolutamente alla fine del carattere &, poiché, se non lo si ponesse, avremmo come risultato un valore in esadecimale di 3 byte ! |1|
Se si vorranno utilizzare esplicite operazioni matematiche anziché funzioni Gambas, si potrà adoperare la seguente formula:
Hex(((&valore \ CInt(2 ^ 8)) And &FF) Or ((&valore * CInt(2 ^ 8)) And &FF00&), 4) As String
oppure
Hex(((&valore \ CInt(2 ^ 8)) And &FF) Or CShort(((&valore * CInt(2 ^ 8)) And &FF00)), 4) As String
Conversione Big-Endian/Little-Endian di un valore a 32bit
La formula astratta per ottenere la conversione Big-Endian/Little-Endian di un valore a 32bit (= 4 byte, ossia di tipo Integer) può essere la seguente:
((valore >> 24) & 0xff) | ((valore << 8) & 0xff0000) | ((valore >> 8) & 0xff00) | ((valore << 24) & 0xff000000)
che in Gambas potremo tradurre quella formula, utilizzando le funzioni di scorrimento dei bit a destra ed a sinistra, in sintassi così:
Hex((Shr(&valore, 24) And &FF) Or (Shl(&valore, 8) And &FF0000) Or (Shr(&valore, 8) And &FF00&) Or (Shl(&valore, 24) And &FF000000), 8) A String
Se si vorranno utilizzare esplicite operazioni matematiche anziché funzioni Gambas, si potrà adoperare la seguente formula:
Hex(((&valore \ CInt(2 ^ 24)) And &FF) Or ((&valore * CInt(2 ^ 8)) And &FF0000) Or ((&valore \ CInt(2 ^ 8)) And &FF00&) Or ((&valore * CInt(2 ^ 24)) And &FF000000), 8)
oppure quest'altra:
Hex(((&valore \ CInt(2 ^ 24)) And &FF) Or ((&valore * CInt(2 ^ 8)) And &FF0000) Or CShort(((&valore \ CInt(2 ^ 8)) And &FF00)) Or ((&valore * CInt(2 ^ 24)) And &FF000000), 8)
Note
[1] Interpellato al riguardo Benoît Minisini ha così spiegato il problema e suggerito la soluzione:
« Because of weird Visual Basic compatibility, &FF00 is sign-extended, i.e. &FF00 = &FFFFFF00
To prevent automatic sign-extension, write &FF00& (with an extra '&' at the end).
Otherwise, I don't know where your data comes from, but Swap$() does endianness conversion provided that each integer is stored inside a string. »