1

I currently have an application that requires me to send data with the least amount of bits possible. For example, if I am giving a direction in degrees then the range is 0 -359. that means with 9 bits, I have a number 0 - 511 with resolution of 1. There would be a 'waste' of 152 possible outcomes. I could use those possible outcomes for error handling, but am wondering if there is any method that could be used to pack in some more data.

The only other thought I had was I could add a multiplication factor of 359/511 so that I can squeeze in a little more precision.

Edit: Additional information:

  1. It should be assumed that not all messages will get through

some field examples:

Direction base(360) Day base(366) hour base(24) minute base(60)

With these three examples the total wasted outcomes is 905.

4

2 回答 2

2

对于一个数字,你显然不能少于 9 位,所以你不能做得更好。但是对于多个数字,您可以做得更好。想到两件事:

您可以在 base 360​​ 中一次传输多个数字。以下是编码三个数字的方法:

int encoded = num0 + 360 * num1 + 360 * 360 * num2;
var decoded0 = encoded / 1 % 360;
var decoded1 = encoded / 360 % 360;
var decoded2 = encoded / 360 / 360 % 360;

如果要使用 a ,则BigInteger可以在无限(或实际上非常多)数字的情况下以这种方式实现理论上的最佳编码。

或者,您可以使用支持 2 种以上备选方案的算术编码变体。使用算术编码,您可以对数字进行增量编码并在可用时提取位。你只需要不断的记忆。

如果您的数字不是均匀分布的(比如 0 的可能性是平时的两倍),算术编码器可以使用该知识来节省更多位。许多通用压缩机都使用这种技术(其中包括 LZMA)。

于 2013-09-23T14:48:28.393 回答
0

对于您给出的特定示例,“方向基数(360)日基数(366)小时基数(24)分钟基数(60)”,事实证明其中两个非常适合55位。(360 x 366 x 24 x 60) 2仅比 2 55小一点。因此,要编码和解码,您只需分别使用乘法和除法(同时获得商和余数)。这可以通过 64 位算术来完成,因此不需要大整数例程。实际上,55 位中只有 0.001 位被浪费了!

因此,direction:day:hour:minute对于范围 1..360、1..366、1..24 和 0..59,序列{a:b:c:d, e:f:g:h}编码为(((((((a - 1) * 366 + (b - 1)) * 24 + (c - 1)) * 60 + d) * 360 + (e - 1)) * 366 + (f - 1)) * 24 + (g - 1)) * 60 + h. 解码取除以 60 的余数得到h. 取那个商,然后除以 24 得到的余数,g - 1以此类推。

然后可以将 55 位序列连接为一个位流,其中 8 个适合 55 个字节。

未使用的 55 位序列可用于终止序列。例如,所有 1 位,除最后一位之外的所有 1 位为零等。可以使用两个不同的终止符来指示倒数第二个 55 位序列是否包含一个或两个向量。

做得更好的唯一方法是利用数字的非均匀分布和/或连续向量之间的相关性。对于后者,您应该考虑这些数字中的部分或全部是否可能与先前向量中的相应数字接近或相同。如果存在这种相关性,那么您可以改为发送差异,并通过一些压缩,大大减少所需的总位数。

于 2013-09-24T04:05:54.480 回答