1

我有一个数组unsigned chars。基本上我有一个位数组。

我知道前 16 位对应于一个无符号整数,我使用它检索它的值(u16)(*(buffer+ 1) << 8 | *abcBuffer)

然后是一个名为的数据类型u30,描述如下: u30 - variable length encoded 30-bit unsigned integer value. u30 的变量编码使用一到五个字节,具体取决于编码值的大小。每个字节将其低七位贡献给该值。如果设置了一个字节的高(第 8)位,则下一个字节也是该值的一部分。

我不明白这个描述:它说u30(三十!)然后它说 1 到 5 个字节?我还有另一种数据类型称为s24 - three-byte signed integer value.

应该如何读取(检索它们的值)这种非典型数据类型?任何帮助将不胜感激。

非常感谢!

4

4 回答 4

4
i=0;    
val = buf[i]&0x7F;
while (buf[i++]&0x80)
{ 
  val |= (buf[i]&0x7F)<<(i*7);
}
于 2010-07-12T18:17:14.327 回答
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 );
于 2010-07-12T18:12:14.273 回答
1

编码格式描述可能有点非正式,但应该足够了。这个想法是你读取一个字节(调用它x),你取最低的 7 位x & 0x7F,同时检查它的最高位是否已设置。您需要编写一个小循环,将 7 位序列合并到一个 uint 变量中,直到当前字节不再设置其最高位。

您必须弄清楚是否需要在数字的高端或低端合并新位 ( a = (a << 7) | (x & 0x7F))。为此,您需要一个测试序列,您知道正确的输出是什么。

于 2010-07-12T18:13:18.670 回答
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 位。

于 2010-07-12T18:21:40.547 回答