Hi,

I have different variables and I want to have a final variable that represents the concatenation of those variables by taking a specific number of bits from each variable. For example, if I have 3 variables var1, var2 and var3 and I want to take 3, 2 and 1 bits respectively from each variable, the final result will be:

``````uint32 var1 = 11; //1011
int32 var2 = 5 /*0101*/, var3 = 3 /*011*/;
uint final_var;
...
final_var = 011011; // 011 from var1 + 01 from var2 + 1 from var3``````

My variables are int and unsigned int and my final variable will be always uint32.

4
Contributors
5
Replies
10
Views
7 Years
Discussion Span
Last Post by miskeen

First of all, when dealing with variables that are larger than one byte, the endianness of the machine might cause portability problems. I'm going to assume you're on an x86 little-endian machine for now.

To get a specific number of bits from a variable, you first need to create a bitmask with the bits that you want to extract set to 1, and those you wish to leave alone set to zero. Then you perform a bitwise AND operation between the mask and the variable you want to work with. Let's say I have a variable 'a' and wish to get the smallest 3 bits.

``````uint_32 a = 11; /* 1011 */
uint_32 mask = 0x7; /* 00000111 */

a now equals 3, the value of its first 3 bits. You can similarly do this for other numbers of bits.

Concatenating the bits together is a little more difficult. First of all, we need to have our sets of extracted bits stored in var1, var2, and var3.

``````uint32 final_var = var1; /* Give it the first bits. */
final_var <<= 2; /* Shift it two bits to the left to make room for var 2. */
final_var |= var2; /* Use the | operator to prevent overflows. */
final_var <<= 1; /* Shift one more bit to make room for var 3. */
final_var |= var3; /* Store var3 and now we're done! */``````

What you have to do is shift the system over by the correct number of bits so that you can have them placed in the right order. We use the OR operator since addition might result in some undesirable effects regarding overflow. These should safely place the bits in the free spots.

If you're using a multi-byte bitfield, I strongly suggest using an array of unsigned chars instead of integers, so that the way the bits are ordered are predictable and portable. Either way, I hope this helps. If you're interested in *why* this works, look up http://en.wikipedia.org/wiki/Bitwise_operation

``final_var = ((((var1 & 0x07) << 2) | (var2 & 0x03)) << 1) | (var3 & 0x01);``

Whats the general form?

From that example, you can do something like this :

``````unsigned int var1 = 11;
long var2 = 5;
long var3 = 3;
unsigned int final_var = var1 &0x3;
final_var <<= 2;
final_var |= (var2 & 0x01);
final_var <<= 1;
final_var |= (var3&0x1);``````