C ++原始数据类型:如何读取无符号30位

时间:2010-07-12 17:56:56

标签: c++ types byte bits

我有一个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.

的数据类型

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

非常感谢!

4 个答案:

答案 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位。