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?

È stato utile?

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.

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