将非二进制值存储到一个唯一的整数中



8位中,我们可以存储01的8个数字。我们还可以说,我们可以在从0255的范围内存储8个不同的数据。

0/1   0/1   0/1   0/1   0/1   0/1   0/1   0/1  → 8 different piece of data
↓     ↓     ↓     ↓     ↓     ↓     ↓     ↓
[bit] [bit] [bit] [bit] [bit] [bit] [bit] [bit] → 8 bits total

如果我们需要存储012而不是存储01,那么我们最终将使用更多的比特。在这种情况下,顺便说一下,我们可以存储0123。然而,这超出了我的需要,但从技术上讲,它将使用相同数量的数据空间。

0/1/2   0/1/2   0/1/2   0/1/2  → 4 different piece of data (expectative)
0/1/2/3 0/1/2/3 0/1/2/3 0/1/2/3 → 4 different piece of data (too much for me)
↓       ↓       ↓       ↓
[2bits] [2bits] [2bits] [2bits] → 8 bits total

我们可以同意我们是";失去";存储容量。解决方案是使用数字基数3进行基数转换(我不知道这是否是正确的术语),这样我们将实现只存储012的目标,并且在相同的8位中,我们可以存储更多信息(<em],老实说,我不知道这些位是如何组织起来的>。)。

示例:

00000₃ → int 0
01212₃ → int 50
11111₃ → int 121
12121₃ → int 151
22222₃ → int 242 (max)

在这种转换中,我们能够存储5条信息,这些信息由012组成,而不是仅存储4条。还有一个";空间";左,这就是我想说的。

我想知道是否有任何方法可以存储混合基数据,而不是固定基

0/1/2   0/1/2    0/1/2/3/4/5/6/7/8  → 3 piece of different data
↓       ↓              ↓
[2bits] [2bits] [      4 bits      ] → 8 bits total

但是,在我看来,我们有空的";空格";再次向左,因为在我看来,它似乎没有使用8位中可能的全部容量,如果我们使用基数转换,也许仍然可以添加更多数据。

问题是:我不知道如何以这种方式处理数据,以可靠地再次合并和拆分数据。

在现实世界中:我需要传输大量使用很少信息的数据(例如数字0到200~10等)。我目前正在对这些数据进行逐位捕捉。在我的情况下,任何优化的字节都是一个非常好的增益(如果这真的可能,也许可以节省20-40%的数据)。

我知道它可能会在重新建立基础、合并和拆分转换上消耗更多的处理,但这不会是一个问题,因为这种处理将在客户端完成(发送时合并,接收拆分),并且服务器管理已经优化的相同数据(没有额外的处理)。

--

可能的解决方案:

让我们想象一下,我有一个由三个数字组成的集合,可以是012,而又有一个三个数字的集合,可以从08(因此每个数字有9种可能性)。目标是将所有这些数字合并为单个整数(在当前最佳方法下,应使用约2字节)。

解决方案1:每个数字都存储在一个完整的字节中:

byte A from 0 to 2
byte B from 0 to 2
byte C from 0 to 2
byte D from 0 to 8
byte E from 0 to 8
byte F from 0 to 8

问题:将需要消耗6个字节来存储这些6个数字

解决方案2:通过位存储

2 bits to store A
2 bits to store B
2 bits to store C
4 bits to store F
4 bits to store G
4 bits to store H
6 unused bits to complete the last byte

问题:除了2位是";超过必要的";为了存储从02(A、B和C)的数字,并且对于从084个比特,我们将使用总共3个字节并且仍然有6个"字节";死的";(未使用的)位,以完成最后一个字节。

解决方案3:分离为两个集合,并分别转换它们各自的碱基:

A, B and C to base 3 consumes 1 byte
D, E and F to base 9 consumes 2 bytes

问题:尽管目前是一个很好的解决方案(尽管有上面的例子,在更复杂的情况下,它可以比解决方案2更优化),这就是我正在使用的,我相信有很多";剩余的";这个联合中的空间,也许仍然可以将所有内容都压缩到2字节中。

例如,222的转换₃最多消耗5个比特,这意味着在这个字节中我们仍然有3个未使用的比特。888₉转换消耗10个比特。这让我看到了只使用15个比特而只使用1个未使用的比特(2个字节)的可能性。

然后我们来讨论下一个解决方案。

解决方案4:移动位以进一步优化空间:

higher bits stores A, B and C
lower bits stores D, E and F

示例:

[5 bits of numbers of base 3] +
[10 bits of numbers of base 9] +
[1 unused bit]

问题:目前这个解决方案甚至比我目前使用的解决方案更好。然而,在通过基数转换和并集可以获得更多信息的情况下,我仍然认为有可能改进。

您可以通过以下方式打包您的值:

示例:

的可能值

a = [0,2] -> 3 states
b = [0,2] -> 3 states
c = [0,8] -> 9 states

假设您有以下值

a := 1
b := 2
c := 8

比你可以通过以下方式计算最终数字

int number = 0; 
int multi = 1; 
number = number.add(multi.multiply(a));
multi = multi.multiply(3)); 
number = number.add(multi.multiply(b));
multi = multi.multiply(3));
number = number.add(multi.multiply(c));

number现在保存您的包装号

打开包装只需要打开

a = number.mod(3)
number = number.divide(3)
b = number.mod(3)
number = number.divide(3)
c = number.mod(9)

相关内容

  • 没有找到相关文章

最新更新