/ / Maneira mais rápida de converter valores de 7 bits em bytes - c, incorporado, byte, bits

Maneira mais rápida de converter valores de 7 bits em bytes - c, embutidos, bytes, bits

Preciso converter 112 bits (16 bytes) de variáveis ​​de valor de 7 bits (eles são recebidos em bytes, mas o MSb precisa ser descartado) em 14 bytes da maneira mais rápida possível em C.

Então, basicamente, o que eu preciso fazer é pegar oprimeiros 7 bits do primeiro byte recebido e deslocá-los para a esquerda e, em seguida, pegue o sétimo bit do segundo byte e coloque-o no primeiro byte para armazenar na posição de bit 0, para que eu entrasse no primeiro byte dos 7 bits do o primeiro byte recebido mais o sétimo bit do segundo byte. Então eu teria que fazer o mesmo com o resto.

A primeira maneira que posso pensar nisso seria o seguinte:

byteToStore [0] = 1 << byteReceived[0] + byteReceived[1] & 1;
byteToStore [1] = 2 << byteReceived[1] + byteReceived[2] & 3;
byteToStore [2] = 3 << byteReceived[2] + byteReceived[3] & 7;

E assim por diante.

Além disso, seria ótimo se pudesse ser feito facilmente com um loop for. Eu poderia fazê-lo com um loop for com meu método, mas não seria tão "limpo".

Obrigado.

Respostas:

2 para resposta № 1

Você deseja compactar alguns bits dos bytes adjacentes em um byte. Isso pode ser conseguido combinando os 7 bits mais baixos do byte esquerdo deslocados para a esquerda com os 7 bits mais baixos do byte direito deslocados para a direita:

void pack(const uint8_t in[16], uint8_t out[14])
{
out[ 0] = (in[ 0] & 0x7f) << 1 | (in[ 1] & 0x7f) >> 6;
out[ 1] = (in[ 1] & 0x7f) << 2 | (in[ 2] & 0x7f) >> 5;
out[ 2] = (in[ 2] & 0x7f) << 3 | (in[ 3] & 0x7f) >> 4;
out[ 3] = (in[ 3] & 0x7f) << 4 | (in[ 4] & 0x7f) >> 3;
out[ 4] = (in[ 4] & 0x7f) << 5 | (in[ 5] & 0x7f) >> 2;
out[ 5] = (in[ 5] & 0x7f) << 6 | (in[ 6] & 0x7f) >> 1;
out[ 6] = (in[ 6] & 0x7f) << 7 | (in[ 7] & 0x7f) >> 0;

out[ 7] = (in[ 8] & 0x7f) << 1 | (in[ 9] & 0x7f) >> 6;
out[ 8] = (in[ 9] & 0x7f) << 2 | (in[10] & 0x7f) >> 5;
out[ 9] = (in[10] & 0x7f) << 3 | (in[11] & 0x7f) >> 4;
out[10] = (in[11] & 0x7f) << 4 | (in[12] & 0x7f) >> 3;
out[11] = (in[12] & 0x7f) << 5 | (in[13] & 0x7f) >> 2;
out[12] = (in[13] & 0x7f) << 6 | (in[14] & 0x7f) >> 1;
out[13] = (in[14] & 0x7f) << 7 | (in[15] & 0x7f) >> 0;
}

Embora exista um padrão claro para cada um dosprovavelmente é mais rápido codificar isso sem um loop, porque a aritmética de controle e deslocamento do loop não levará tempo. O código pode ser acelerado pré-calculando uma matriz de entrada auxiliar com todos os bits mais significativos já removidos, para que você não é necessário extrair os 7 bits mais baixos (x & 0x7f) duas vezes para cada bit. (O último deslocamento à direita por 0 não faz nada, mas o compilador o otimizará. Guardei por simetria.)