There is a 2 byte packet. The first 5 bits represent the version, the next 5 bits represent the type, and the last 6 bits represent the value. I am passing the packet as a char*
to a function (print_pak
). In that function, I want to print the version, type, and packet value. How can I do that?
void print_pak(char* pak)
{
}
You need to use bit masking and shifting for this. Also, when doing bit manipulation, I believe it's preferred to work with unsigned integer types since the binary representation of negative integers is not defined by the C standard.
void
print_pak(const unsigned char *pak)
{
unsigned char version, type, value;
version = (pak[0] >> 3);
type = ((pak[0]&0x07) << 2) + (pak[1] >> 6);
value = pak[1]&0x3f;
printf("Version = %u, Type = %u, Value = %u\n", version, type, value);
}
Here's how this works. The <<
and >>
operators are for bit shifting. Suppose you have an unsigned char
, x
, which holds the bits 10111010. Shifting it right by 3 bits is done by (x >> 3)
(operator precedence always trips me up when doing bit manipulation so I throw in parentheses to be safe). The right three bits can't go anywhere and so they fall off. The result is 00010111. Shifting to the left works the same (sort of).
Bit masking, &
, implements binary "and". That is, if x
is 10101011 and y
is 00011111, then x&y
only has 1's where x
and y
share them. So, it would be 00001011.
Let's take all of this and tackle your problem. The version is the first five bits of the first byte. Therefore, we want to right shift the low three bits off.
The type is the last three bits of the first byte followed by the first two bits of the second byte. That first group can be acquired by masking off the high five bits of the first byte (0x07
is 00000111 in binary). The second group can be acquired by right shifting the second byte by six bits. Then, to put them together, you need to left shift the first group by two bits to make room for the second group.
Finally, the value is the low six bits of the second byte which can be acquired by a simple masking of those bits (0x3f
is 00111111 in binary).