【问题标题】:Combine two integers into one and decode them later将两个整数合二为一,稍后解码
【发布时间】:2012-06-14 18:38:37
【问题描述】:

使用 C++,我需要将两个不同的 ID 组合成一个 16 位整数。然后稍后我需要将这个 16 位整数解码为两个原始 ID 值。

例子:

// Store two integers into one
unsigned short Identifier1 = 12793; //(maximum number 30000)
unsigned short Identifier1 = 5450; //(maximum number 30000)
unsigned short CombinedIDs = 34283; // this is example, I don't know the code for that

// Decode one integer into two
// At this point I only have CombinedIDs value, I need to extract it
// into the two original IDs

unsigned short OriginalIdentifier1 = ...CombinedIDs.. code to get 12793
unsigned short OriginalIdentifier2 = ...CombinedIDs.. code to get 5450

【问题讨论】:

  • 信息论告诉我们,这在一般情况下是不可能的。如果您的标识符的最大值为 30000,那么它们每个需要 15 位来存储。它们一起包含 30 位信息。不能将 30 位信息压缩成 16 位整数。
  • 如果您需要最大 30k,我会考虑使用 32 位结果。
  • 这不是作业。我需要将两个 ID 存储到一个 16 位整数中 - 2 个字节,位于 IP 数据包中的某个位置。
  • @MarcusFrenkel:仍然不可能。最大数量 100 需要 7 位,30000 需要 15 位。加起来是 22 位,仍然超过 16 位。
  • 如果可以的话那就太好了,因为重复应用这个原理,任何一台电脑只要一个存储字就能搞定。

标签: c++ integer


【解决方案1】:

这是不可能的。

假设您的两个标识符可以在[0, 30000] 范围内,则有 30000 x 30000 = ~2^30 对可能的标识符。但是,只有 2^16 个可能的 16 位数字。因此,您不可能将标识符对映射到 16 位整数并期望从中恢复标识符。


相反,您可以使用 32 位整数来存储组合,在这种情况下编码和解码都很简单:

编码:

unsigned short Identifier1 = 12793;
unsigned short Identifier2 = 5450;
unsigned int CombinedIDs = (Identifier1 << 16) | Identifier2;

解码:

unsigned short Identifier1 = CombinedIDs >> 16;
unsigned short Identifier2 = CombinedIDs & 0x0000FFFF

请注意,现在不必限制标识符在 [0, 30000] 范围内 - 它们是任何无符号短值。


编辑回答您的评论:4 位和 12 位都是可能的。

编码:

unsigned short Identifier1;  // 4 bits
unsigned short Identifier2;  // 12 bits
unsigned short CombinedIDs = (Identifier1 << 12) | Identifier2;

解码:

unsigned short Identifier1 = CombinedIDs >> 12;
unsigned short Identifier2 = CombinedIDs & 0x0FFF;

【讨论】:

  • 你能告诉我如何将 4bit 和 12bit 整数合二为一,然后再解码吗?如果不可能,那么至少是两个 8 位整数的情况。谢谢。
【解决方案2】:

您不能将两个小于 30000 的数字组合起来,然后将其填充为 16 位小数。

要能够表达 30,000 个唯一的可能值,您至少需要 15 位(2^15 是 32,768)。

如果您必须选择两个数字,每 30,000 个唯一的可能值,则可能的总数为 900,000,000,这需要至少 30 位(2^30 为 1,073,741,824)。

尝试使用 int。

unsigned short Identifier1 = 29999;
unsigned short Identifier2 = 1;
unsigned int combined = identifier1<<16 + identifier2;

unsigned short extracted1 = (combined & 0xffff0000)>>16;
unsigned short extracted2 = combined & 0xffff;

【讨论】:

  • 谢谢。上一个回复在前,所以我需要接受那个回复。
猜你喜欢
  • 2015-10-24
  • 1970-01-01
  • 2016-07-27
  • 2015-12-30
  • 2019-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-06
相关资源
最近更新 更多