long - C#3 byte Ints
unsigned long (5)
¿Puedes? Por supuesto. Va a ahorrar espacio? Tal vez, dependiendo de la cantidad de trabajo que quieras hacer. Tienes que entender que el procesador es de 32 bits, lo que significa que tiene registros de 4 bytes, así es como va a querer almacenar y acceder a cosas. Para forzar un "int" de 3 bytes, deberá mantenerlo en una matriz de bytes y extraerlo de la matriz a una dirección alineada antes de su uso. Eso significa que si lo almacena en corto, el compilador lo rellenará (y perderá la eficiencia que cree haber creado) o será mucho 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 de 1 byte por elemento? La penalización de perf por el acceso a elementos puede cambiar la forma en que es crítico ese byte.
Yo diría que si ese 1 byte es realmente importante, tal vez, solo quizás, estés usando el lenguaje equivocado de todos modos. La cantidad de bytes que guardarías si no instalas y usas el CLR en primer lugar es muchos de esos bytes.
Nota al margen: también harías un cambio, no una multiplicación (aunque el compilador probablemente llegaría para ti).
Estoy trabajando en un proyecto en el que necesito tratar en el nivel de bytes con enteros. Como ahorrar espacio es una consideración primordial, solo necesito cantidades muy pequeñas (y de longitud variable).
¿Hay alguna manera de que pueda convertir el int ''4096'' en 3 bytes? o ''1053'' en un 2 bytes?
Obviamente, puedo hacerlo manualmente = (byte [0] * 256) + (byte [1]), pero me preguntaba si existe una opción más fácil para convertir el int en x bytes y viceversa.
Solo por una locura añadida, hagámoslo en C # usando el viejo truco sindical 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 quieras "convertir", haz esto:
OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;
Pero eso realmente solo ayuda si está buscando "ahorrar" el costo de desplazar un byte de una palabra. No he analizado el SMIL generado, por lo que no sé si esto es más barato en comparación con cualquier otra solución.
Tienes que hacer un poco de cambio. Es mucho más fácil si trabajas con HEX, ya que cada número (me refiero a cada dígito, pero el dígito es para la base 10, hexágono) representa cuatro bits.
BitConverter.GetBytes
te dará los bytes.
y
BitConverter.ToInt32
obtendrá un int de 32 bits de los bytes.
Podría hacer una codificación de entero de longitud variable. El antiguo método de hace años era usar el bit alto de cada byte para indicar que el entero continúa en otro byte. Así que pierdes un bit por byte, pero ganas 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
así que 0-127 toman 1 byte y 128-16383 toman 2 bytes, etc ...
Para formas más complejas de hacer esto echa un vistazo a esta página