Domanda
Sto lavorando a un progetto in cui devo trattare a livello di byte con numeri interi. Dato che il risparmio di spazio è una considerazione preminente, ho solo bisogno di dimensioni molto piccole (e di lunghezza variabile).
Esiste un modo per trasformare int '4096' in 3 byte? o "1053" in 2 byte?
Ovviamente posso farlo manualmente = (byte [0] * 256) + (byte [1]), ma mi chiedevo se esiste un'opzione più semplice per convertire gli int in x byte e viceversa?
Soluzione
Puoi? Sicuro. Salverà spazio? Forse, a seconda di quanto lavoro vuoi fare. Devi capire che il processore è a 32 bit, il che significa che ha registri a 4 byte, quindi è così che vorrà archiviare e accedere alle cose. Per forzare un "int" a 3 byte dovrai tenerlo in un array di byte ed estrarlo dall'array in un indirizzo allineato prima dell'uso. Ciò significa che se lo memorizzi brevemente, il compilatore o lo eliminerà (e perderai l'efficienza che pensi di aver creato) o sarà lotto più lento da leggere e scrivere.
Se si tratta di un'app desktop, in che modo il risparmio di spazio è una considerazione primaria, soprattutto quando si parla di 1 byte per elemento? La penalità perfetta per l'accesso agli elementi può farti riflettere su quanto sia critico quel byte.
Direi che se quel 1 byte è veramente importante, forse, forse, stai usando la lingua sbagliata comunque. Il numero di byte che salveresti non installando e utilizzando CLR in primo luogo è un lotto di quei byte.
Nota a margine: faresti anche un turno, non una moltiplicazione (anche se il compilatore probabilmente ci arriverebbe per te).
Altri suggerimenti
Solo per una maggiore follia, facciamolo in C # usando il vecchio trucco dell'unione in stile C:
[StructLayout(LayoutKind.Explicit)]
struct OddUnion
{
/* The 32-bit integer value */
[FieldOffset(0)]
public int IntegerValue;
/* The bytes that overlap with it */
[FieldOffset(0)]
public byte Byte1;
[FieldOffset(1)]
public byte Byte2;
[FieldOffset(2)]
public byte Byte3;
[FieldOffset(3)]
public byte Byte4;
}
E poi, quando vuoi " convertire " ;, fai questo:
OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;
Ma questo aiuta davvero solo se stai cercando di " salvare " il costo dello spostamento di bit di un singolo byte da una parola. Non ho esaminato lo SMIL generato, quindi non so se sia più economico rispetto a qualsiasi altra soluzione.
È possibile eseguire la codifica di numeri interi di lunghezza variabile. Il vecchio metodo di anni fa era usare il bit alto di ogni byte per indicare che l'intero continua su un altro byte. Quindi perdi un bit per byte, ma guadagni piccoli numeri interi. Ciò è utile soprattutto nella memorizzazione persistente in cui conta ogni ultimo byte.
Esempio: supponiamo di avere a che fare con numeri interi senza segno, avremmo
int binary
0 00000000
1 00000001
...
127 01111111
128 00000001 10000000
129 00000001 10000001
...
255 00000001 11111111
256 00000010 10000000
...
16383 01111111 11111111
16384 00000001 10000000 10000000
quindi 0-127 richiede 1 byte e 128-16383 richiede 2 byte, ecc ...
Per modi più complessi di farlo consulta questa pagina
BitConverter.GetBytes
ti darà i byte.
e
BitConverter.ToInt32
ti darà un int a 32 bit dai byte.
Devi fare un po 'di spostamento. È molto più semplice se lavori con HEX, poiché ogni numero (intendo ogni cifra, ma cifra è per base 10, hex git) rappresenta quattro bit.