Search code examples
cbitmapbit-manipulationbit-shift

Bit manipulation and masking in c


I am working on some c problems. I have one process that needs to be executed and has bit manipulations. I have 2 variables with uint8 type say uint8 bit_Part1 & uint8 bit_Part2 (U8 each). I want to add values to these variables having values one is U4 and other U6 like U4_part1 and U6_part2 and one boolean value Bool_Part3 I want to place them into these uint8 bit_Part1 & uint8 bit_Part2 structure as below

enter image description here

So far i tried shifting like:

Its psudo code:

uint8 bitman_u8_part1 =0;
    uint8 bitman_u8_part2 =0;
    bitman_u8_part1 |= ((uint8)(U4_Part1));  // 0000\\\\ 
    bitman_u8_part1 | = ((uint8)((U6_Part2 >> 2)<<4));// append 0000 for the empty 
    bitman_u8_part2 | =((uint8)(EC2_TCH_BITMAP_U6_Part2<<4));
    bitman_u8_part2 | =((bool)BOOL_Part3 & 1<<4);

Here is an example of what I expect to see:

If U4_part1=0111, U6_Part2=001111, Bool_Part3=1(true)

then the expected result is: bit_Part1 & uint8 bit_Part2 both will contain data -> 00000|1|00||1111|0111

(note I have added | just for separation between data || is for separation of uint8 bit_Part1 & uint8 bit_Part2).

Additional values are in uint8 bit_Part2 are filled with 0, compare with picture above (& U4 means value with 4 bits U6 as in with value with 6 bits)

How can i do it?

UPDATE:

Something that i have tried again :

 unsigned int U4_data1 = 12;    /* 60 = 0000 1100 */  
   unsigned int U6_data2 = 53;  /* 21 = 0011 0101 */
   unsigned int Bool_data3 =1;
   unsigned int U8_part1 =0;
   unsigned int U8_part2 = 0;
   U8_part1 = U4_data1;
   U8_part1 |= (U6_data2<<4);
   printbinary(U8_part1);
   U8_part2 |= U6_data2>>4;
   U8_part2 |= (Bool_data3)<<2;

Solution

  • // Assemble the pieces in a temporary object:
    uint16_t temp =   Bool_Part3 << 10
                    | U6_part2   <<  4
                    | U4_part1   <<  0;
    
    // Redivide the temporary object into the destination parts:
    uint8_t bit_Part1 = temp >> 0;
    uint8_t bit_Part2 = temp >> 8;
    

    If Bool_Part3 has some integer type that you are calling Boolean even though it is not a standard _Bool or bool (declared in <stdbool.h>) type and may have a value other than 0 or 1, then an appropriate way to ensure 0 or 1 is inserted in the result is to cast it to _Bool, as with:

    uint16_t temp = (_Bool) Bool_Part3 << 10 …
    

    While you can use other idioms, such as !!Bool_Part3, the cast has the advantage of explicitly expressing the desired operation, a conversion to 0 or 1. (While programmers 30 years ago had to use various workarounds in C, there is no reason to program kludges the way people did decades ago when modern expressions are available.)

    Notes:

    • uint8_t and uint16_t are declared in <stdint.h>.
    • Shifts by zero are shown for illustration and uniformity. They may be omitted.