我有一个unsigned chars
数组。基本上我有一个位数组。
我知道前16位对应于无符号整数,我使用(u16)(*(buffer+ 1) << 8 | *abcBuffer)
然后是一个名为u30
的数据类型,描述如下:
u30 - variable length encoded 30-bit unsigned integer value
。 u30的变量编码使用一到五个字节,具体取决于编码值的大小。每个字节将其低7位提供给该值。如果设置了一个字节的高(第8)位,则下一个字节也是该值的一部分。
我不明白这个描述:它说u30
(三十!)然后说1到5个字节?我还有另一种名为s24 - three-byte signed integer value.
如何读取(检索其值)这种非典型数据类型?任何帮助将不胜感激。
非常感谢!
答案 0 :(得分:4)
i=0;
val = buf[i]&0x7F;
while (buf[i++]&0x80)
{
val |= (buf[i]&0x7F)<<(i*7);
}
答案 1 :(得分:2)
假设我理解正确(总是有问题),以下内容将会读取这些值。它在此示例中从位置0开始(i
需要被缓冲区中的实际位置偏移):
unsigned int val;
unsigned char buf[300];
int i;
int shift;
i = 0;
buf[0] = 0x81;
buf[1] = 0x3;
val = 0;
shift = 0;
do
{
val |= (0x7F & buf[i] ) << shift;
shift += 7;
i++;
} while (( buf[i-1] & 0x80 ) && ( i < 5 ));
printf( "Val = %u\n", val );
答案 2 :(得分:1)
编码格式描述可能有些不正式,但应该足够了。想法是你读取一个字节(称之为x
),你取最低7位x & 0x7F
并同时检查它是否设置了最高位。您需要编写一个小循环,将7位序列合并到一个uint变量中,直到当前字节不再具有最高位设置。
您必须弄清楚是否需要合并高端的新位或数字的低端(a = (a << 7) | (x & 0x7F)
)。为此,您需要一个测试序列,其中您知道正确的输出是什么。
答案 3 :(得分:0)
要读取可变长度30位值,您可以执行以下操作:
const char HIGH_BIT = 0x80;
const char DATA_MASK = 0x7F;
const char LAST_MASK = 0x03; // only need 2 bits of last byte
char tmpValue = 0; // tmp holder for value of byte;
int value = 0; holder for the actual value;
char* ptr = buffer; // assume buffer is at the start of the 30 bit number
for(int i = 0; i < 5; i++)
{
if(i == 4)
{
tmpValue = LAST_MASK & *ptr;
}
else
{
tmpValue = DATA_MASK & *ptr;
}
value |= tmpValue << ( 7 * i);
if(!(HIGH_BIT & *ptr))
{
break;
}
if(i != 4)
{
++ptr;
}
}
buff = ptr; // advance the buffer afterwards.
@Mark:我在输入时发布了你的答案,除了高字节外,还能正常工作。该值仅为30位,因此只有高字节的前2位用于该值,并且您使用的是该值的全部8位。