Reputation: 3367
I'm having a little trouble grabbing n bits from a byte.
I have an unsigned integer. Let's say our number in hex is 0x2A, which is 42 in decimal. In binary it looks like this: 0010 1010. How would I grab the first 5 bits which are 00101 and the next 3 bits which are 010, and place them into separate integers?
If anyone could help me that would be great! I know how to extract from one byte which is to simply do
int x = (number >> (8*n)) & 0xff // n being the # byte
which I saw on another post on stack overflow, but I wasn't sure on how to get separate bits out of the byte. If anyone could help me out, that'd be great! Thanks!
Upvotes: 27
Views: 77688
Reputation: 1
I think there is a much simpler way to do what you want. You only need the & "and" operator.
Basically, if you want the 5 most significant bits, all you have to do is add them up. 128+64+32+16+8 = 248 or the 3 least significant bits would be 4+2+1=7. Then use the and operator ( & ) with your variable and the total to assign those bits to a new variable.
int main()
{
unsigned char c = 42; //sum of 3rd bit + 5th bit + 7th bit
int first5 = c & 248; //sum of bits 1-5
int last3 = c & 7; // sum of bits 6-8
cout << "first 5 " << first5 << " last 3 " << last3 << endl;
cout << "OR 5 most significant bits " << first5 << endl;
cout << "and 3 least significant bits " << last3 <<endl;
return 0;
}
But, you can also use this to grab one individual bit or any combination of bits.
For instance...
int threenfive = c&40; //would extract the 3rd bit and 5th bit
because the 3rd bit = 32 and the 5th = 8 and the sum of the two = 40.
Upvotes: 0
Reputation: 241721
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 review 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.
Upvotes: 29
Reputation: 129374
"grabbing" parts of an integer type in C works like this:
&
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;
Upvotes: 20
Reputation: 3299
You could use bitfields for this. Bitfields are special structs where you can specify variables in bits.
typedef struct {
unsigned char a:5;
unsigned char b:3;
} my_bit_t;
unsigned char c = 0x42;
my_bit_t * n = &c;
int first = n->a;
int sec = n->b;
Bit fields are described in more detail at http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000
The charm of bit fields is, that you do not have to deal with shift operators etc. The notation is quite easy. As always with manipulating bits there is a portability issue.
Upvotes: 9
Reputation: 15758
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 = 00101b
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b
Upvotes: 13
Reputation: 5064
int x = (number >> 3) & 0x1f;
will give you an integer where the last 5 bits are the 8-4 bits of number
and zeros in the other bits.
Similarly,
int y = number & 0x7;
will give you an integer with the last 3 bits set the last 3 bits of number
and the zeros in the rest.
Upvotes: 2
Reputation: 46259
just get rid of the 8* in your code.
int input = 42;
int high3 = input >> 5;
int low5 = input & (32 - 1); // 32 = 2^5
bool isBit3On = input & 4; // 4 = 2^(3-1)
Upvotes: 1