【问题标题】:How to extract few bits or bytes from a byte array? [closed]如何从字节数组中提取几个位或字节? [关闭]
【发布时间】:2019-12-13 20:23:40
【问题描述】:

我想要一个函数来帮助我从字节数组的起始位位置提取几个位或字节。字节数组的顺序为LSB。代码骨架如下:

typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, uint8 *ByteArray, uint16 BitsWanted)
{
    uint16 Result;
    ...
}

如何在C 中实现这个逻辑?非常感谢任何示例或起点。

【问题讨论】:

  • StartBit除以8来计算数组中的起始索引。然后计算要移动的位数和AND 掩码以仅获取必要的位。
  • C 在<stdint.h> 中定义了uint16_tuint8_t 类型——也许你应该改用它们。
  • @AnttiHaapala 是的,你是对的,但这些是项目细节。
  • 这是起点:stackoverflow.com/questions/15255692/…;可能是>> 3/ 8;和& 7 或`% 8`。
  • 是的...您的输出可能跨越几个字节,因此您通常必须获取低字节,然后向下移动,获取高字节,然后向上移动或进入结果。

标签: c arrays bit-manipulation bit endianness


【解决方案1】:

您的问题没有完全说明:LSB 指的是跨越一个字节以上的整数类型在内存中的字节顺序。在您的情况下,您必须指定位在数组中的编号方式和组合方式以形成提取的值。

从 0 开始对位进行编号是有意义的,这样位 n 是偏移量 n / 8 的字节中具有值 1 << (n % 8) 的位。为保持一致性,编号最小的位应成为提取值的最低有效位。此约定与 LSB 一致,因为在偏移量 0 处提取 16 位会产生存储在数组前 2 个字节中的 uint16 的值。

这是一个使用此约定的简单实现:

typedef unsigned char uint8;
typedef unsigned short uint16;

uint16 ExtractBitsOrBytes(uint16 StartBit, const uint8 *ByteArray, uint16 BitsWanted) {
    // assuming BitsWanted <= 16
    uint16 result = 0;
    uint16 i;
    for (i = 0; i < BitsWanted; i++) {
        result |= (uint16)((ByteArray[StartBit >> 3] >> (StartBit & 7)) & 1) << i;
        StartBit++;
    }
    return result;
}

但是请注意,在许多系统上用于单色位图的约定是不同的:最左边的像素对应于第一个字节的最高有效位,该约定继承自 70 年代后期做出的选择,混合 MSB 和 LSB,使得图形软件比应有的复杂。

【讨论】:

  • 我知道为什么会出现这种情况BitsWanted &lt;= 16 ?遇到BitsWanted = 32怎么办?
  • @Dennis.M:如果你想一次提取超过 16 位,如果函数更大,则使返回类型。 uint16 可能只有 16 位。还要更改result 的类型和演员(uint16)
猜你喜欢
  • 2017-03-02
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 2020-01-03
  • 1970-01-01
  • 2011-11-22
  • 2015-04-14
  • 2017-01-16
相关资源
最近更新 更多