Grabbing n bits from a byte
Integers are represented inside a machine as a sequence of bits; fortunately for us humans, programming languages provide a mechanism to show us these numbers in decimal (or hexadecimal), but that does not alter their internal representation.
You should revise the bitwise operators &
, |
, ^
and ~
as well as the shift operators <<
and >>
, which will help you understand how to solve problems like this.
The last 3 bits of the integer are:
x & 0x7
The five bits starting from the eight-last bit are:
x >> 3 // all but the last three bits & 0x1F // the last five bits.
"grabbing" parts of an integer type in C works like this:
- You shift the bits you want to the lowest position.
- You use
&
to mask the bits you want - ones means "copy this bit", zeros mean "ignore"
So, in you example. Let's say we have a number int x = 42;
first 5 bits:
(x >> 3) & ((1 << 5)-1);
or
(x >> 3) & 31;
To fetch the lower three bits:
(x >> 0) & ((1 << 3)-1)
or:
x & 7;
Say you want hi
bits from the top, and lo
bits from the bottom. (5 and 3 in your example)
top = (n >> lo) & ((1 << hi) - 1)bottom = n & ((1 << lo) - 1)
Explanation:
For the top, first get rid of the lower bits (shift right), then mask the remaining with an "all ones" mask (if you have a binary number like 0010000
, subtracting one results 0001111
- the same number of 1
s as you had 0
-s in the original number).
For the bottom it's the same, just don't have to care with the initial shifting.
top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101bbottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b