Let's say I have a couple of variables like apple, orange, banana
I have 8 apples, 1 orange, 4 bananas.
Is it possible to somehow convert those values into a single integer and also revert back to their original values based on the computed integer value?
I found an example online.
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);
But it doesn't seem to work as it should when I entered random numbers.
How to do this
Yes, you can do this. The simple way to do this is what you are doing now, which is to allocate different bits of the integer to different values. Yours is something like this, for a 32-bit 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 |
When you bitshift the value eight to the right, then you're taking just the age parts of the number. If you bitshift seven to the right and mask it with 1, i.e. value >>> 7 & 1
, then you get the gender back. And if you just mask out the bottom seven bits (i.e. value & 0x7F
), then you get the height.
Why it's fragile
Your example is missing something important: the range of the values. For example, the height value can never go higher than 127. If you try to store a height of 128 or higher, then the way you're writing it now will result in part of the height overwriting the gender, because you need eight bits to store a value that large. That's why random numbers don't work.
In the same way, if someone accidentally puts in a gender that isn't zero or one, then it'll mess up part of the age value, because you just can't store a number that high in a single bit.
The way to fix this in the assignment is by putting in the bit masks, like so:
packed_info = (((age << 1) | (gender & 1)) << 7) | (height & 0x7f);
When doing it this way, then you can be sure that gender won't overwrite age, and height won't overwrite the others. However, if you put in a height greater than 127, it'll be used mod 127.
Why you usually shouldn't
Because it's bug-prone and integers don't take very much memory. You can't just remember it's an int
anymore, you need to remember what the bit layout looks like. It's easier to just keep three int
s.
However, this sort of thing is still done when transmission speed matters. (For example, digital TV or other video, digital audio, the Ethernet protocols, etc.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With