Reputation: 373
I want to extract a particular range of bits in an integer variable.
For example: 0xA5 (10100101)
I want to extract from bit2 to bit5. i.e 1001 to a variable and count number of zeros between them.
I have another variable which give the starting point, which means in this case the value of the variable is 2. So the starting point can be find by 0xA5 >> 2. 5th bit position is a random position here..means it can be 6 or 7. The main idea is whichever bit is set to 1 after 2nd bit. I have to extract that..
How can I do rest of the part ?
Upvotes: 1
Views: 613
Reputation: 373
int32_t do_test(int32_t value, int32_t offset)
{
int32_t _zeros = 1;
value >>= offset;
int i = 1;
while(1) {
if((value >> i) % 2 == 0) {
_zeros += 1;
i++;
} else {
break;
}
}
}
Upvotes: 1
Reputation: 9203
Assuming you are dealing with unsigned int
for your variable.
You will have to construct the appropriate mask.
Suppose you want the bits from position x
to position y
, there need to be y - x + 1
1s
in the mask.
You can get this by -
int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
Now you need to remove the lower x
bits from the initial number, which be done by -
unsigned int result = number >> x;
Finally apply the mask to remove the upper bits -
result = result & mask;
Upvotes: 2
Reputation: 409356
If you want bits from the offset X
then shift right by X
.
If you want Y
bits, then then mask (after the shift) will be 2 to the power of Y
minus one (for your example with four bits, 2 to the power of 4 is 16, minus one is 15 which is 1111
binary). This can be dome by using left-shifting by Y
bits and subtracting 1
.
However, the masking isn't needed if you want to count the number of zeros in the wanted bits, only the right shift. Loop Y
times, each time shifting a 1
left one step, and check using bitwise and if the value is zero. If it is then increment a counter. At the end of the loop the counter is the number of zeros.
To put it all in code:
// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
// Get the bits we're interested in the rightmost position
value >>= offset;
unsigned int counter = 0; // Zero-counter
for (unsigned int i = 0; i < bits; ++i)
{
if ((value & (1 << i)) == 0)
{
++counter; // Bit is a zero
}
}
return counter;
}
To use with the example data you have:
count_zeros(0xa5, 2, 4);
The result should be 2
. Which it is if you see this live program.
Upvotes: 1
Reputation: 474
You could use a mask and the "&" (AND) operation:
a = 0xA5;
a = a >> OFFSET; //OFFSET
mask = 0x0F; // equals 00001111
a = a & mask;
In your example a = 0xA5 (10100101), and the offset is 2.
Upvotes: 1
Reputation: 795
int result = (0xA5 >> 2) & 0x0F;
Truth table for the &
operator
| INPUTS | OUTPUT |
-----------------------
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
-----------------------
Upvotes: 0
Reputation: 2106
In this example we put 0 or 1 values into array. After that you can treat array as you like.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint8_t value = 0xA5;
unsigned char bytes[8];
unsigned char i;
for (i = 0; i < 8; i++) {
bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
}
for (i = 0; i < 8; i++) {
printf("%d", bytes[i]);
}
return 0;
}
Upvotes: 1