I need to extract specific part (no of bits) of a short
data type in C.
For Example I have a binary of 52504 as 11001101000 11000 and I want First 6 ( FROM LSB --> MSB i.e 011000 decimal 24) bits and rest of 10 bits ( 11001101000 decimal 820).
Similarly I want this function to be too generalized to extract specific no of bits given "start" and "end" (i.e chunks of bits equivalent with some decimal value).
I checked other posts, but those were not helpful, as given functions are not too much generalized.
I need something that can work for short
data type of C.
I am having the short array of size 2048 bytes. Where each Pixel is of 10 bits. So my 16 bit consisting each byte occupying some time 2 pixels data, sometimes 3 pixels data.
Like
( PIXEL : 0,1 ) 10 BITS + 6 BITS
then ( PIXEL : 1,2,3 ) 4 BITS ( 1st pixels remaining bits ) + 10 BITS + 2 BITS.
and so on ..this pattern continues ... So, all I want to extract each pixel and make an entire array of having each pixels to be occupied wholy in on WHOLE BYTE ( of 16 bits ) like.. 1 byte should contain 1 DATA PIXEL, the other BYTE should contain other PIXEL value in whole 16 bits and so on so forth.
Here we create a mask, apply the mask to n, and then right shift the masked value to get just the bit we want. We could write it out more fully as: int mask = 1 << k; int masked_n = n & mask; int thebit = masked_n >> k; You can read more about bit-masking here.
Bit manipulation is the act of algorithmically manipulating bits or other pieces of data shorter than a byte. C language is very efficient in manipulating bits.
You can mask out the bits you want from a byte using bitwise AND. In general, to test for individual bits, C has bitwise operators. Example: SO: C/C++ check if one bit is set in, i.e. int variable.
There are two building blocks that you need to know to build this yourself:
N
least significant bits requires constructing a bit mask with N
ones at the end. You do it like this: ((1 << N)-1)
. 1 << N
is 2 ^ N
: it has a single 1
at the N+1
st position, and all zeros after it. Subtracting one gives you the mask that you need.M
least significant bits is a simple shift to the right: k >> M
Now your algorithm for cutting out from M
to N
becomes a two-step process: you shift the original value M
bits to the right, and then perform a bit-wise AND
with the mask of N-M
ones.
#define LAST(k,n) ((k) & ((1<<(n))-1))
#define MID(k,m,n) LAST((k)>>(m),((n)-(m)))
int main() {
int a = 0xdeadbeef;
printf("%x\n", MID(a,4,16));
return 0;
}
This fragment cuts out bits from 4, inclusive, to 16, exclusive, and prints bee
when you run it. Bits are numbered from zero.
unsigned short extract(unsigned short value, int begin, int end)
{
unsigned short mask = (1 << (end - begin)) - 1;
return (value >> begin) & mask;
}
Note that [begin, end)
is a half open interval.
It can be done like this:
mask = ~(~0 << (end - start + 1));
value = (n >> start) & mask;
where n
is the original integer and value
is the extracted bits.
The mask
is constructed like this:
1. ~0 = 1111 1111 1111 1111 1111 1111 1111 1111
2. ~0 << (end - start + 1) = 1111 1111 1111 1111 1100 0000 0000 0000
// assuming we are extracting 14 bits, the +1 is added for inclusive selection
// ensure that end >= start
3. ~(~0 << (end - start + 1)) = 0000 0000 0000 0000 0011 1111 1111 1111
Now n
is shifted right by start
bits to align the desired bits to the left.
Then a bitwise AND gives the result.
//To get value from specific position 'pos' to 'pos+offset' in number 'value'
#define bitGet(value, offset, pos) (((1ull << offset) - 1) & (value >> (pos - 1)))
//Set value 'newval' from position 'pos' to 'pos+offset' in number 'value'
#define bitSet(value, offset, pos, newval) \
(~(((1ull << offset) - 1) << (pos - 1)) & value) | ((((1ull << offset) - 1) & newval) << (pos - 1))
Although its a very old question, I would like to add a different solution. Using macros,
/* Here, startBit : start bit position(count from LSB) endBit : end bit position(count from LSB) .NOTE: endBit>startBit number : the number from which to extract bits maxLength:the total bit size of number. */ `
#include <stdio.h>
#define getnbits(startBit,endBit,number,maxLength) \
( number & ( (~0U >> (maxLength-endBit)) & (~0U << startBit) ) )
int main()
{
unsigned int num=255;
unsigned int start=1,end=5,size=sizeof(num)*8;
printf("Inputs : %d %d %d %d \n ",start,end,num,size);
printf("Input number : %d\n",num);
if(end>start)
{
int result = getnbits(start,end,num,size-1);
printf("Output : %u\n\n",result);
}
else
printf("Error : EndBit is smaller than starBit!\n\n");
return 0;
}
`
Output :
Inputs : 1 5 255 32
Input number : 255
Output : 62
Here, 255 = 11111111 and 62 = 00111110
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