如何实现这个
是的,你可以实现这个。最简单的方法就是当前你正在做的,即将整数的不同位分配给不同的值。对于32位整数来说,你正在做的可能类似于:
|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 |
当你将一个数值右移八位进行位操作时,你只获取到了这个数字的年龄位。如果你将这个数值右移七位,并使用掩码1(即
value >>> 7 & 1
),那么你就可以得到性别信息。如果你只是从底部七位中获取信息(即
value & 0x7F
),那么你就可以得到身高信息。
为什么它容易出问题
你的示例缺少一些重要的内容:值的范围。例如,身高值永远不可能超过127。如果你尝试存储128或更高的身高值,那么现在的写法将导致身高的一部分覆盖性别信息,因为你需要八位来存储这么大的值。这就是为什么随机数不起作用的原因。
同样地,如果有人不小心输入了不是0或1的性别信息,那么它将破坏年龄值的某一部分,因为你无法在单个位中存储这么高的数值。
在赋值中修复这个问题的方法是通过添加位掩码,像这样:
packed_info = (((age << 1) | (gender & 1)) << 7) | (height & 0x7f);
这种做法可以确保性别不会覆盖年龄,身高也不会覆盖其他信息。但是,如果输入的身高大于127,它将对127取模后再使用。
通常为什么不建议这样做
因为这容易出现错误,而且整数占用的内存并不多。你不能只记住它是一个int
,还需要记住位布局的样子。保持三个int
更容易。
然而,在传输速度很重要的情况下,仍然会使用这种方法。例如数字电视或其他视频、数字音频、以太网协议等。