Pregunta

Estoy trabajando en un proyecto en el que necesito tratar a nivel de bytes con enteros. Dado que ahorrar espacio es una consideración primordial, solo necesito muy pequeños (y entradas de longitud variable).

¿Hay alguna manera de convertir el int '4096' en 3 bytes? o '1053' en 2 bytes?

Obviamente, puedo hacerlo manualmente = (byte [0] * 256) + (byte [1]), pero me preguntaba si hay una opción más fácil para convertir el int en x bytes y volver de nuevo?

¿Fue útil?

Solución

¿Puedes? Por supuesto. ¿Ahorrará espacio? Tal vez, dependiendo de cuánto trabajo quieras hacer. Debe comprender que el procesador es de 32 bits, lo que significa que tiene registros de 4 bytes, así que así es como querrá almacenar y acceder a las cosas. Para forzar un byte de 3 '' int '' deberá mantenerlo en una matriz de bytes y extraerlo de la matriz a una dirección alineada antes de usarlo. Eso significa que si lo almacena brevemente, el compilador lo rellenará (y perderá cualquier eficiencia que crea que ha creado) o será un lote más lento para leer y escribir.

Si se trata de una aplicación de escritorio, ¿cómo es exactamente el ahorro de espacio una consideración principal, especialmente cuando se habla 1 byte por elemento? La penalización de rendimiento para el acceso al elemento puede cambiarle de opinión sobre la importancia de ese byte.

Yo diría que si ese 1 byte es realmente importante, que tal vez, solo tal vez, estás usando el lenguaje incorrecto de todos modos. La cantidad de bytes que guardaría si no instalo y uso CLR en primer lugar es un lote de esos bytes.

Nota al margen: También harías un cambio, no una multiplicación (aunque el compilador probablemente lo conseguiría por ti).

Otros consejos

Solo para agregar locura, hagámoslo en C # usando el viejo truco de unión estilo 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;
 }

Y luego, cuando desee " convertir " ;, haga esto:

OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;

Pero eso realmente solo ayuda si está buscando "guardar" El costo de desplazar un bit a bit de una palabra. No he mirado el SMIL generado, así que no sé si es más barato en comparación con cualquier otra solución.

Podría hacer una codificación entera de longitud variable. El viejo método de hace años era usar el bit alto de cada byte para denotar que el entero continúa a otro byte. Entonces pierde un bit por byte, pero gana números enteros pequeños. Esto es principalmente útil en el almacenamiento persistente donde cada último byte cuenta.

Ejemplo: Supongamos que estamos tratando con enteros sin signo, tendríamos

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 

entonces 0-127 toma 1 byte y 128-16383 toma 2 bytes, etc ...

Para formas más complejas de hacer esto, consulte esta página

BitConverter.GetBytes obtendrá los bytes.

y

BitConverter.ToInt32 obtendrá un int 32 bit de los bytes.

Tienes que hacer algunos cambios. Es mucho más fácil si trabaja con HEX, ya que cada número (quiero decir cada dígito, pero el dígito es para base 10, hexadecimal) representa cuatro bits.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top