我正在处理其值中具有各种奇怪位数的数据(例如3位或71位,您可以想象的任何东西),所有数据都紧密地序列化在一起。为了提取数据,我想我首先要创建一个能够逐位检索的函数,然后我可以将这些函数绑定在一起超过8位。
现在我感到非常困惑,这是我与之合作的内容:
unsigned char Data[] = { 0, 255, 2, 255, 4, 5, 6, 7 };
UInt64 BitLen = 64; //test data
UInt64 ByteLen = BitLen % 8 == 0 ? BitLen / 8 : BitLen / 8 + 1;
....
unsigned char GetUChar(UInt64 BitIdx) {
UInt64 ByteIdx = BitIdx / 8;
UInt16 Bulk = ByteLen - 1 == ByteIdx ? Data[ByteIdx] : *(UInt16*)&Data[ByteIdx];
return Bulk >> (8 - (BitIdx - ByteIdx)) % 8;
}
这个想法是,如果包含BitIdx的字节是数据集中的最后一个,则将值检索为char,否则检索为UInt16(应该获取该字节和下一个字节)。 然后
BitOffset = BitIdx - ByteIdx * 8
8 - BitOffset =从左边填充多少
最后和%8,这样如果BitIdx与ByteIdx对齐,则移位量= 0.
然后我将它移到右边并返回低位字节。
所以为了测试,我使用在线十进制到二进制转换器来找出二进制的测试数据是
00000111 00000110 00000101 00000100 11111111 00000010 11111111 00000000
我使用该函数从BitIdx 14开始查找char,结果为10111111,而需要10000001
有一段时间我认为这些位是倒退然后是字节但是没有任何意义了。有没有更简单的方法从字节数组中从位地址Y开始提取X位数?
答案 0 :(得分:0)
您忘记将ByteIdx
乘以8,然后再从BitIdx
中减去它:
return Bulk >> ((8 - (BitIdx - 8*ByteIdx)) % 8);
注意:使用在分割前添加ByteLen
的常见技巧可以简化计算N-1
:
UInt64 ByteLen = (BitLen + 7) / 8;
答案 1 :(得分:0)
请注意,如果您在小端系统(例如Intel)上运行,那么读取两个字节作为UInt16 将为您提供这些字节&#34;向后&#34;。< / p>
e.g。
char b[] = {1,0};
UInt16 w = *(Uint16*)&b[0];
提供w == 1
(00000000 00000001
)而不是256
(00000001 00000000
),如您所料。