将值打包成单个int

use*_*907 4 java

假设我有几个变量,如苹果,橙子,香蕉

我有8个苹果,1个橙子,4个香蕉.

是否有可能以某种方式将这些值转换为单个整数,并根据计算的整数值还原为原始值?

我在网上找到了一个例子.

int   age, gender, height;
short packed_info;
. . .
// packing
packed_info = (((age << 1) | gender) << 7) | height;
. . .
// unpacking
height = packed_info & 0x7f;
gender = (packed_info >>> 7) & 1;
age    = (packed_info >>> 8);
Run Code Online (Sandbox Code Playgroud)

但是,当我输入随机数时,它似乎不起作用.

jpr*_*ete 11

这该怎么做

是的,你可以这样做.执行此操作的简单方法是您现在正在执行的操作,即将整数的不同位分配给不同的值.对于32位int,你的是这样的:

|3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1     |      |             |
|1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 |  7   |6 5 4 3 2 1 0|
|                     Age                        |Gender|   Height    |
Run Code Online (Sandbox Code Playgroud)

当您将值8移位到右侧时,您只需要使用数字的年龄部分.如果你向右移位七并用1掩盖它value >>> 7 & 1,那么你就会得到性别.如果你只是掩盖了最后七位(即value & 0x7F),那么你就得到了高度.

为什么它很脆弱

您的示例缺少重要的内容:值的范围.例如,高度值永远不会高于127.如果您尝试存储128或更高的高度,那么您现在编写它的方式将导致部分高度覆盖性别,因为您需要8位存储一个大的值.这就是随机数不起作用的原因.

同样地,如果有人意外地输入了不是零或一个性别的性别,那么它会弄乱部分年龄值,因为你不能存储一个高位的数字.

在赋值中修复此问题的方法是通过放入位掩码,如下所示:

packed_info = (((age << 1) | (gender & 1)) << 7) | (height & 0x7f);
Run Code Online (Sandbox Code Playgroud)

当这样做时,你可以确定性别不会覆盖年龄,高度不会覆盖其他人.但是,如果你的高度大于127,它将被用于mod 127.

为什么你通常不应该

因为它容易出错并且整数不会占用太多内存.你不能再记住它int了,你需要记住位布局的样子.保持三个更容易int.

然而,当传输速度很重要时,这种事情仍然存在.(例如,数字电视或其他视频,数字音频,以太网协议等)