Pergunta
Eu estou trabalhando em um projeto onde eu preciso para lidar no nível de byte com inteiros. Desde economia de espaço é uma consideração primária, eu só preciso muito pequenas (e variáveis ??ints de comprimento).
Existe uma maneira que eu posso transformar o int '4096' em 3 bytes? ou '1053' em um 2 bytes?
Obviamente eu CNA fazê-lo manualmente = (byte [0] * 256) + (byte [1]), mas eu queria saber se existe uma opção mais fácil para converter o int em x bytes e vice-versa?
Solução
Você pode? Certo. Será que vai salvar qualquer espaço? Talvez, dependendo da quantidade de trabalho que você quer fazer. Você tem que entender que o processador é de 32 bits, o que significa que tem 4 registros byte, então é assim que ele vai querer armazenar e coisas de acesso. Para forçar um "int"-byte 3 você vai ter que mantê-lo em um array de bytes, e extraí-lo a partir da matriz para um endereço alinhado antes do uso. Isso significa que se você armazená-lo curto, o compilador quer pad-lo (e você vai perder qualquer eficiência que você acha que você criou) ou ele vai ser um muito mais lento para ler e escrever.
Se este é um aplicativo de desktop, como exatamente é economia de espaço a principal consideração, especialmente quando se fala 1 byte por elemento? A pena perf para acesso elemento pode mudar se importa sobre como crítico que um byte é.
Eu diria que, se que 1 byte é verdadeiramente importante, que talvez, apenas talvez, você está usando o idioma errado de qualquer maneira. O número de bytes que você salvar o meu não instalar e usar o CLR em primeiro lugar é uma muito desses bytes.
Nota lateral:. Você também faria uma mudança, não uma multiplicação (embora o compilador provavelmente chegar lá para você)
Outras dicas
Apenas para a loucura adicionado, vamos fazê-lo em C # usando o truque de estilo C união velho:
[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 então, quando você quer "Convert", faça o seguinte:
OddUnion myOddUnion;
myOddUnion.IntegerValue = 4096;
Byte secondByte = myOddUnion.Byte1;
Mas isso realmente só ajuda se você estiver olhando para "salvar" o custo do bit de mudança de um único byte de uma palavra. Eu não olhei para o SMIL gerado, então eu não sei se este é mais barata em comparação com qualquer outra solução.
Você poderia fazer a codificação comprimento inteiro variável. O método de idade de anos atrás era usar o bit de cada byte para indicar que o número inteiro continua a outro byte. Então, você perde um pouco por byte, mas ganhar inteiros pequenos. Isto é principalmente útil no armazenamento persistente, onde cada último byte conta.
Exemplo: Suponha que estamos a lidar com números inteiros sem sinal, terí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
para 0-127 take 1 byte e 128-16383 leva 2 bytes, etc ...
Para formas mais complexas de se fazer isso check-out desta página
BitConverter.GetBytes
você irá obter os bytes.
e
BitConverter.ToInt32
vai te dar um int de 32 bits dos bytes.
Você tem que fazer alguma mudança bit. É muito mais fácil se você trabalhar com HEX, uma vez que cada número (quero dizer, todos os dígitos, mas dígito é de base 10, hex git) representam quatro bits.