C 将7位值转换为字节的最快方法

C 将7位值转换为字节的最快方法,c,embedded,byte,bits,C,Embedded,Byte,Bits,我需要以C语言中最快的方式将112位(16字节)的7位值变量(它们以字节形式接收,但必须丢弃MSb)转换为14字节 所以基本上,我需要做的是,把接收到的第一个字节的前7位移到左边,然后把第二个字节的第7位放到第一个字节中,存储在第0位,这样我就能在第一个字节中得到接收到的第一个字节的7位加上第二个字节的第7位。那我就得对其他人做同样的事 我能想到的第一个方法是: byteToStore [0] = 1 << byteReceived[0] + byteReceived[1] &

我需要以C语言中最快的方式将112位(16字节)的7位值变量(它们以字节形式接收,但必须丢弃MSb)转换为14字节

所以基本上,我需要做的是,把接收到的第一个字节的前7位移到左边,然后把第二个字节的第7位放到第一个字节中,存储在第0位,这样我就能在第一个字节中得到接收到的第一个字节的7位加上第二个字节的第7位。那我就得对其他人做同样的事

我能想到的第一个方法是:

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

byteToStore[0]=1您希望将相邻字节中的一些位打包为一个字节。这可以通过组合左移位字节的最低7位与右移位字节的最低7位来实现:

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;
}
void pack(常量输入[16],常量输出[14])
{
out[0]=(in[0]&0x7f)>6;
out[1]=(in[1]&0x7f)>5;
out[2]=(in[2]&0x7f)>4;
out[3]=(in[3]&0x7f)>3;
out[4]=(in[4]&0x7f)>2;
out[5]=(in[5]&0x7f)>1;
out[6]=(in[6]&0x7f)>0;
out[7]=(in[8]&0x7f)>6;
out[8]=(in[9]&0x7f)>5;
out[9]=(in[10]&0x7f)>4;
out[10]=(in[11]&0x7f)>3;
out[11]=(in[12]&0x7f)>2;
out[12]=(in[13]&0x7f)>1;
out[13]=(in[14]&0x7f)>0;
}

虽然每个块都有一个清晰的模式,但是在没有循环的情况下编写代码可能会更快,因为循环控制和移位算法不会花费任何时间。通过预先计算已删除所有最高有效位的辅助输入数组,可以加快代码速度,这样就不必为每个位提取两次最低7位(
x&0x7f
)。(最后一次右移0没有任何作用,但编译器会对其进行优化。我保留它是为了对称。)

我认为您混淆了移位操作数:移位对象是左的,移位宽度是右的。另外,你可能会得到一个左移位和一个右移位,而不是一个移位和一个按位and。我曾经想过类似的事情,但我一直在寻找一个“可扩展”的东西,因为将来我可能不得不对192位或更多的位做同样的事情。不管怎样,现在我将按照你的建议实施它。非常感谢。它已经可以扩展了:您可以调用例程
pack56
,然后抛出以
out[7]
开头的后半部分。然后您可以使用
pack112
调用
pack56(in,out)
pack56(in+8,out+7)
。函数
pack168
另外调用
pack56(in+16,out+14)
。此外,正如我所说,有一个清晰的模式,您可以将逻辑滚动到一个更灵活的循环中。我只是认为使用硬编码索引而不是循环的变体可能会更快。不过,我还没有对此进行测试,这个假设更多的是基于直觉。@Twistx77:您要求的是“尽可能快”,这可能与“可扩展”(您将添加一个循环开销)是互斥的。然而,“尽可能快”是一个无用的要求。够快就够好了。可以通过展开隐含循环使其快速,也可以通过使用两个嵌套循环使其变小。