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

发布于 2024-09-09 00:03:39 字数 441 浏览 0 评论 0原文

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

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

然后是一个名为 < code>u30 说明如下: u30 - 可变长度编码的 30 位无符号整数值。 u30 的变量编码使用一到五个字节,具体取决于编码值的大小。每个字节将其低七位贡献给该值。如果设置了一个字节的高(第 8)位,则下一个字节也是该值的一部分。

我不明白这个描述:它说 u30(三十!),然后又说 1 到 5 个字节?另外,我还有另一种数据类型,称为 s24 - 三字节有符号整数值。

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

多谢!

I have an array of unsigned chars. Basically I have an array of bits.

I know that the first 16 bits corresponds to an unsigned integer and I retrieve its value using (u16)(*(buffer+ 1) << 8 | *abcBuffer)

Then comes a data type called u30 which is described as follows:
u30 - variable length encoded 30-bit unsigned integer value. The variable encoding for u30 uses one to five bytes, depending on the magnitude of the value encoded. Each byte contributes its low seven bits to the value.If the high (8th) bit of a byte is set then the next byte is also part of the value.

I don't understand this description: it says u30(thirty!) and then it says 1 to 5 bytes? Also I have another data type called s24 - three-byte signed integer value.

How should one read (retrieve their values) such non-typical data types? Any help will be appreciated.

Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巴黎盛开的樱花 2024-09-16 00:03:39
i=0;    
val = buf[i]&0x7F;
while (buf[i++]&0x80)
{ 
  val |= (buf[i]&0x7F)<<(i*7);
}
i=0;    
val = buf[i]&0x7F;
while (buf[i++]&0x80)
{ 
  val |= (buf[i]&0x7F)<<(i*7);
}
初见 2024-09-16 00:03:39

假设我理解正确(始终是一个值得怀疑的问题),下面将读取这些值。在此示例中,它从位置零开始(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 );

Assuming I understand correctly (always a questionable matter), the following will read the values. It starts at position zero in this example (i would need to be offset by the actual position in the buffer):

   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 );
夏见 2024-09-16 00:03:39

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

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

The encoding format description is somewhat informal perhaps, but should be enough. The idea will be that you read one byte (call it x), you take the lowest 7 bits x & 0x7F and at the same time check if it's highest bit is set. You'll need to write a small loop that merges the 7 bit sequences in a uint variable until the current byte no longer has its highest bit set.

You will have to figure out if you need to merge the new bits at the high end, or the low end of the number (a = (a << 7) | (x & 0x7F)). For that you need one test sequence of which you know what the correct output is.

人海汹涌 2024-09-16 00:03:39

要读取可变长度 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 位。

To read the variable length 30 bit value, you could do something like such:

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: your answer was posted while I was typing this, and would work except for the high byte. the value is only 30 bits, so only the first 2 bits of the high byte are used for the value and you are using the full 8 bits of the value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文