C++ C++;基本数据类型:如何读取无符号30位

C++ C++;基本数据类型:如何读取无符号30位,c++,types,byte,bits,C++,Types,Byte,Bits,我有一个无符号字符数组。基本上我有一个位数组 我知道前16位对应一个无符号整数,我使用(u16)(*(buffer+1)检索它的值,假设我理解正确(始终是一个有问题的问题),下面将读取值。在本例中,它从零位开始(I需要被缓冲区中的实际位置偏移): unsigned int val; 无符号字符buf[300]; int i; int移位; i=0; buf[0]=0x81; buf[1]=0x3; val=0; 移位=0; 做 { val |=(0x7F&buf[i])假设我理解正确(始终是一个

我有一个
无符号字符数组
。基本上我有一个位数组


我知道前16位对应一个无符号整数,我使用
(u16)(*(buffer+1)检索它的值,假设我理解正确(始终是一个有问题的问题),下面将读取值。在本例中,它从零位开始(
I
需要被缓冲区中的实际位置偏移):

unsigned int val;
无符号字符buf[300];
int i;
int移位;
i=0;
buf[0]=0x81;
buf[1]=0x3;
val=0;
移位=0;
做
{

val |=(0x7F&buf[i])假设我理解正确(始终是一个有问题的问题),下面将读取值。在本例中,它从零位开始(
i
需要被缓冲区中的实际位置偏移):

unsigned int val;
无符号字符buf[300];
int i;
int移位;
i=0;
buf[0]=0x81;
buf[1]=0x3;
val=0;
移位=0;
做
{

val |=(0x7F&buf[i])编码格式描述可能有点不正式,但应该足够了。您可以读取一个字节(称为
x
),取最低的7位
x&0x7F
,同时检查是否设置了最高位。需要编写一个小循环,将7位序列合并到uint变量中,直到当前字节不再设置其最高位


您必须弄清楚是否需要在数字的高端或低端合并新位(
a=(a编码格式描述可能有点非正式,但应该足够了。您的想法是读取一个字节(称之为
x
),取最低的7位
x&0x7F
,同时检查是否设置了最高位。需要编写一个小循环,将7位序列合并到uint变量中,直到当前字节不再设置其最高位

您必须弄清楚是否需要在数字的高端或低端合并新位(
a=(a
i=0;
val=buf[i]&0x7F;
while(buf[i++]&0x80)
{ 
val |=(buf[i]&0x7F)
i=0;
val=buf[i]&0x7F;
while(buf[i++]&0x80)
{ 

val |=(buf[i]&0x7F)要读取可变长度的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.
常量字符高位=0x80;
const char DATA_MASK=0x7F;
const char LAST_MASK=0x03;//只需要最后一个字节的2位
char tmpValue=0;//字节值的tmp holder;
int值=0;实际值的持有者;
char*ptr=buffer;//假设buffer位于30位数字的开头
对于(int i=0;i<5;i++)
{
如果(i==4)
{
tmpValue=最后一个掩码和*ptr;
}
其他的
{
tmpValue=数据屏蔽和ptr;
}

value |=tmpValue要读取可变长度的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.
常量字符高位=0x80;
const char DATA_MASK=0x7F;
const char LAST_MASK=0x03;//只需要最后一个字节的2位
char tmpValue=0;//字节值的tmp holder;
int值=0;实际值的持有者;
char*ptr=buffer;//假设buffer位于30位数字的开头
对于(int i=0;i<5;i++)
{
如果(i==4)
{
tmpValue=最后一个掩码和*ptr;
}
其他的
{
tmpValue=数据屏蔽和ptr;
}

value |=tmpValue它是1到5个字节,因为每个字节只使用7位,所以4个字节只能代表28位;您需要所有5个字节来代表30位的值。这是从哪里来的?一些旧架构,如DEC的PDP-10,使用了6位字节。5*7=30。我看不出这里有什么混淆。不过,要回答您的问题:使用5位字节便宜的龙舌兰酒可以治好你的头痛。@Neil:事实上,即使在今天,在很多地方都使用这种可变长度编码。例如,Java和.NET二进制序列化程序都使用它们。CLR程序集元数据块中的几乎所有整数都是以类似的方式编码的。@Noah:
5*7=30
?你有多少龙舌兰酒?它有多少是1到5个字节,因为每个字节只使用7位,所以4个字节只能代表28位;你需要所有5个字节来代表30位的值。这是从哪里来的?一些旧的架构,如DEC的PDP-10,使用了6位字节。5*7=30。我看不出这里有什么混淆。不过,要回答你的问题:用五分之一的廉价龙舌兰酒尼尔:事实上,即使在今天,在很多地方都使用这种可变长度编码。例如,Java和.NET二进制序列化程序都使用它们。CLR程序集元数据块中的几乎所有整数都是以类似的方式编码的。@Noah:
5*7=30
?您喝了多少龙舌兰酒?可能会添加一个错误ck以检测第5字节设置了太多位的情况,因此结果不适合30位?OP中不明确的是“机器”是大端还是小端。如果它是大端,你只需在循环中每次将val移动7,而不是将当前字节向上移动n*7次。人们还必须想一想,如果字节5设置了其前6位中的任何一位(如David所说),会发生什么。你关于端的观点是正确的。我确实考虑过这一点,并且(无可否认地)只是简单的解决方法。我只是根据我将如何编写编码(写入7个低位)、右移、提取下一个7位等做了一个猜测。可能会添加一个错误检查来检测第5个字节设置了太多位的情况,因此结果不适合30位?OP中的含糊不清之处在于是否“机器”是大端还是小端。如果它是大端,你只需在循环中每次将val移动7,而不是将当前字节向上移动n*7次。人们还必须想一想,如果字节5设置了其前6位中的任何一位(如David所说),会发生什么。你关于端的观点是正确的。我确实考虑过这一点,并且(无可否认地)刚拿了
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.