实现动态位域

时间:2011-12-30 07:05:22

标签: algorithm encoding compression decoding bit-fields

重点是以下问题会发生什么。

- int数组的元素,比方说长5,5,6,7,9位(它们是不同的)。

如何对其进行编码,使其占用32位而不是通常的160位?

我还想说另一方面(解码方面)我不知道每个元素有多大。那么,如果我收到这样的数据,怎么可能解码,或者换句话说,我怎样才能以一种可以轻松解码的方式进行编码?

3 个答案:

答案 0 :(得分:2)

如果事先知道这些数字中的位分布,那很简单:只需将数组中每个元素的位放到结果int中的正确位置,就像这样(例如在C ++代码中):

unsigned int encoded = (val[0]) | (val[1] << 5) | (val[2] << 10) |
              (val[3] << 16) | (val[4] << 23);

...假设val是一个int数组,并且它包含5,5,6,7和9位长的数字。解码同样简单:

int decoded[5];
decoded[0] = encoded & 0x1F;
decoded[1] = (encoded >> 5) & 0x1F;
decoded[2] = (encoded >> 10) & 0x3F;
decoded[3] = (encoded >> 16) & 0x7F;
decoded[4] = (encoded >> 23);

如果事先不知道比特长度,并且唯一已知的事实是,它们的比特大小合计为32,那么,对于一般情况,将它们编码为最大值是不可能的 32位;因为你已经需要这个位来存储实际的数字;但你还必须知道编码数字的位长;为此你需要额外的存储空间。如果这些数字在某种程度上是多余的并且可以被压缩,则这一切都是有效的。

当然有一些方法可以使每个整数短于4个字节;根据要处理的数字的确切属性,一种或另一种算法可能更适合;这里有一些可能的算法的简短列表:

前两种方法的缺点是它们只能表示固定的最大位数。这种处理属于压缩的范畴,对于更多的理论分析,请务必阅读有关该主题的一些文献;正如Kaganar的评论所指出的,这里特别感兴趣的是Universal Codes;上面列表中的最后两个算法就是这样的通用代码。对于5,5,6,7和9位的5个值的示例输入,它们应该降低到48位(对于4位小于8位的值,4位8位,对于9位,1位16位)数)。这两种方法对列表中其他方法的优势在于它们适用于任意大的数字;可能有其他Universl代码更适合您的目的,请务必查看其他代码。

答案 1 :(得分:0)

您可以在每个包含元素位大小的元素之前包含4-6位,具体取决于元素的最大大小(如果最大大小为4,则为4,如果最大大小为<5,则为5,6)如果最大尺寸<64)。

解码就像:

  • 读取4位以确定元素大小
  • 读取x位作为元素(其中x是元素大小)

由于大小可变,您将无法将数据打包为32个字节,因为您需要为每个元素包含某种大小指示符。在这种情况下,假设您使用4位大小,您将使用52位,这只是原始大小160位的32.5%。

答案 2 :(得分:0)

我认为将5,5,6,7,9压缩成32位是不可能的。存储空间太小,无法容纳所有信息。

首先,我们可以通过观察元素的最大可能位来最小化填充位。如果我们使用32位变量来获得最大10位元素,那么我们就浪费了22位。我们可以使用10位数据类型消除每个元素22位。

除了这个需要一些膨胀,放气方案,我认为它不适合小数据或数字阵列,如OP的例子。