【问题标题】:C++ Reading signed 32-bit integer valueC++ 读取带符号的 32 位整数值
【发布时间】:2011-03-15 22:17:54
【问题描述】:

我有一个名为 s32 的多字节原始类型,我想从字节数组中读取它。

规格如下:

  • 它是一个 32 位有符号整数值,以 little-endian 顺序存储。

  • 负整数使用 2 的补码表示。

  • 根据大小使用 1 到 5 个字节。每个字节将其低七位贡献给该值。如果设置了高(第 8 位)位,则下一个字节也是值的一部分。

  • 应用符号扩展:传播编码的最后一个字节的第七位以填充解码值的 32 位。

对于 U32 - 无符号 32 位,我想出了这个(欢迎任何 cmets!),但不知道如何为 S32 修改它。

char temp = 0; 
u32 value = 0;
size_t index = 0;

for(int i = 0; i < 5; i++)
{
    if(i < 4)
    {
        temp  = 0x7F & buffer[index];
    }
    else
    {
        temp = 0x0F & buffer[index];
    }

    value |= temp << (7 * i);

    if(!(0x80 & buffer[index])) break;

    ++index;
}

谢谢大家!

【问题讨论】:

  • 前几天有人问了一个几乎相同的问题……我看看能不能找到。
  • > •它使用 1 到 5 个字节 - 32 位肯定是 1 到 4 个字节?
  • @Cogwheel:对于无符号整数的情况,我自己也可能如此。 Signed-ness 今天抓住了我,不知道如何处理补码。抱歉,如果我过度使用电路板(顺便说一句,这是我的第二篇文章:)@graham.reeds:这也让我感到困惑,但不,你需要 5 个字节,因为你只使用每个字节的 7 位,所以你有最后四位留给第 5 个字节。
  • 不,他的意思是1到5,这是一种压缩方案。
  • 既然是 2 的恭维和符号扩展,阅读有符号和无符号应该没有区别。

标签: c++ bytearray 32-bit signed


【解决方案1】:

您是否在使用 little-endian 系统?
如果是这样,下面应该可以解决问题。

if(!(0x80 & buffer[index])) 
{
  if(0x40 & buffer[index])  value = -value;
  break;
}

如果您在大端系统上需要小端值的负数,那就有点棘手了,但这个要求对我来说似乎很奇怪

【讨论】:

    【解决方案2】:

    我在answer to this question 中发布了SIGN_EXTEND 宏。对于您的代码,我会将您的 u32 value 更改为 s32 value,并将 SIGN_EXTEND 应用为

    // after loop close
    SIGN_EXTEND(value, index * 7, u32);
    

    使用该问题的公认答案,您会说:

    if(value > (1 << (index * 7 - 1))
        value -= (1 << (index * 7));
    

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 2019-05-30
      • 2011-01-31
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多