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
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;
// 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>
. I would suggest something along these lines:
#define LOW_4_MASK 0xF
#define LOW_2_MASK 3
#define BOOL_PART3_BIT = 1 << 2;
bit_Part1 = (U4_Part1 & LOW_4_MASK) | ((U6_part2 & LOW_4_MASK) << 4);
bit_Part2 = (U6_part2 >> 4) & LOW_2_MASK;
if (Bool_Part3)
bit_Part2 |= BOOL_PART3_BIT;
I don't know the types of all your variables here, or whether there exists the possibility of having other bits set, outside the six bit range of U6_part2
, for example. The masking prevents stray bits, set in error, from propagating into your resulting bit_Part1
and bit_Part2
variables.
I handled the boolean separately because a boolean in much C code including your excerpt as written, is an integer (only newer C standard have modified this, and much C code does not use the newer bool definitions); any non-zero value counts as "true". If you come into this piece of code with Bool_Part3
set to, for example, 0xFFF0, you certainly do not want to OR it into your result. Even if you mask it to the lowest bit, you may not get the correct result.
Here is another method using union. Just replace 1 with your boolean variable, 15 with U6 and 7 with U4.
#include <stdio.h>
int main()
{
struct st_bitman_u8 {
unsigned char part1;
unsigned char part2;
}bitman_u8;
union Data {
short sum;
struct st_bitman_u8 _bitman_u8;
}data;
short sum1 = 1 << 10; //1 is Bool_Part3
short sum2 = 15 << 4; //15 is U6_Part2
short sum3 = 7; //7 is U4_part1
data.sum = sum1+sum2+sum3;
printf("part1 %d part2 %d",data._bitman_u8.part1, data._bitman_u8.part2);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.