【问题标题】:C: Correct way to process 24-bit 2's complement numberC:处理 24 位 2 的补码的正确方法
【发布时间】:2018-12-06 07:23:22
【问题描述】:

我有一组 32 位数据的样本集,格式为 24 位,2 的补码,MSB 在前。数据精度为18位;未使用的位为零。 我想处理这个样本集中的数字以找到它们的平均值。

但是,我不确定如何将所有数字转换为相同的类型,然后使用它们来计算平均值。

一种方法是将样本集中的所有数字右移14位。这样我直接得到18个有用位(因为它是18位精度的24位数据,所以只提取18个有用位)。 然后我可以直接用这些数字来计算它们的平均值。

以下是数据样本的示例样本集:-

  • 0xF9AFC000

  • 0xF9AFC000

  • 0xF9AE4000

  • 0xF9AE0000

  • 0xF9AE0000

  • 0xF9AD0000

  • 0xF9AC8000

  • 0xF9AC8000

  • 0xF9AC4000

  • 0xF9AB4000

  • 0xF9AB8000

  • 0xF9AB4000

  • 0xF9AA4000

  • 0xF9AA8000

  • 0xF9A98000

  • 0xF9A8C000

  • 0xF9A8C000

  • 0xF9A8C000

  • 0xF9A88000

  • 0xF9A84000

但是,18 位数字仍然具有符号位 (MSB)。该位并不总是设置,可能是 0 或 1,具体取决于数据。

我是否应该通过 &ing 所有数字与 0x1FFFF 来掩盖符号位并使用它们来计算平均值?

或者我应该先将它们从 2 的补码转换为整数,方法是取反加 1?

请建议一种从 32 位数字中提取和处理“24 位,2 的补码,MSB 在前”数字的正确方法。

提前致谢!

【问题讨论】:

  • 可能的重复,看看reversing two's complement for 18bit int - 包含多个指向相关答案的链接。 (含14-bit二人恭维)
  • 您的话不够清楚,无法理解数据的格式。你应该画一张 32 位字的图片,并显示未使用的位是如何设置的。负 2 补码数以高位全 1 开头。一个问题是32位的高字节是负数全1还是0?
  • MCVE (minimal reproducible example) 的数据有两部分:输入和预期输出。您提供了输入;谢谢。你期望输出什么?看起来所有的值都是负数;那是对的吗?并且所有值的最低有效位都有 14 个零位?还有一个“你试过什么”的问题,因此实际输出与预期输出。
  • C 中没有“十进制整数”这样的数据类型。int 和朋友存储整数,而不是“十进制整数”。 printf 输出的是十进制表示。它是在您使用%d 或类似格式字符串时创建的。
  • 您可能想检查您的系统是否执行有符号或无符号移位:stackoverflow.com/questions/7622/… 如果它执行有符号移位,这就是您所需要的。 (以牺牲便携性为代价。)

标签: c twos-complement


【解决方案1】:

好吧,提供示例数据并不是一个完整的规范,但让我们看看

F9AFC000

看起来数据在高位 3 个字节中。这是一个猜测。如果它们确实是 24 位的 2 补码,那么将真值转换为 32 位 int 就可以了

int32_t get_value_from_datum(uint32_t datum) {
  return (int32_t) datum >> 8; 
}

在示例中,这将扩展前导 F 的高位。结果将是FFF9AFC0。作为以 10 为底的 2 的补码整数,这是-413760

或者您的意思是,感兴趣的 18 位在 32 位字中完全左对齐。然后就是

int32_t get_value_from_datum(uint32_t datum) {
  return (int32_t) datum >> 14; 
}

这导致 -6465。

正如我在评论中所说,您需要更清楚地解释数据格式。

精确的规范最容易显示为 32 位字的图片,MSB 到 LSB,它标识哪些 18 位是数据位

【讨论】:

    猜你喜欢
    • 2017-10-17
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2010-12-08
    • 2011-02-28
    • 2016-01-15
    相关资源
    最近更新 更多