[英]Bit manipulation and masking in c
I am working on some c problems.我正在处理一些 c 问题。 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).我有 2 个 uint8 类型的变量,例如
uint8 bit_Part1
和uint8 bit_Part2
(每个为 U8)。 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我想为这些变量添加值,一个是
U4
,另一个是U6
,如U4_part1
和U6_part2
,还有一个 boolean 值Bool_Part3
我想将它们放入这些uint8 bit_Part1
和uint8 bit_Part2
结构中,如下所示
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)如果 U4_part1=0111,U6_Part2=001111,Bool_Part3=1(真)
then the expected result is: bit_Part1 & uint8 bit_Part2 both will contain data -> 00000|1|00||1111|0111那么预期的结果是:bit_Part1 & uint8 bit_Part2 都将包含数据 -> 00000|1|00||1111|0111
(note I have added | just for separation between data || is for separation of uint8 bit_Part1 & uint8 bit_Part2). (注意我添加了 | 只是为了数据之间的分离 || 是为了分离 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) uint8中的附加值bit_Part2用0填充,对比上图(&U4表示4位的值,U6表示6位的值)
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:如果
Bool_Part3
有一些 integer 类型,你正在调用 Boolean 即使它不是标准的_Bool
或bool
(在<stdbool.h>
中声明)类型并且可能有一个不是 0 或 1 的值,那么一个适当的方法来确保 0 或在结果中插入 1 是将其转换为_Bool
,如下所示:
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.)虽然您可以使用其他习语,例如
!!Bool_Part3
,但强制转换的优点是可以显式表达所需的操作,转换为 0 或 1。(虽然 30 年前的程序员不得不在 C 中使用各种变通方法,但没有理由以人们几十年前现代表达方式可用时的方式来编程 kludges。)
Notes:笔记:
uint8_t
and uint16_t
are declared in <stdint.h>
. uint8_t
和uint16_t
在<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.我不知道这里所有变量的类型,或者是否存在设置其他位的可能性,例如
U6_part2
的六位范围之外。 The masking prevents stray bits, set in error, from propagating into your resulting bit_Part1
and bit_Part2
variables.屏蔽可防止错误设置的杂散位传播到生成的
bit_Part1
和bit_Part2
变量中。
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);我单独处理了 boolean,因为 boolean 在很多 C 代码中,包括您所写的摘录,是一个 integer(只有更新的 C 标准修改了这个,很多 C 代码不使用新的 bool 定义); 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.例如,如果您将
Bool_Part3
设置为 0xFFF0 并进入这段代码,您当然不希望将它与结果进行“或”运算。 Even if you mask it to the lowest bit, you may not get the correct result.即使你把它屏蔽到最低位,你也可能得不到正确的结果。
Here is another method using union.这是使用 union 的另一种方法。 Just replace 1 with your boolean variable, 15 with U6 and 7 with U4.
只需将 1 替换为您的 boolean 变量,将 15 替换为 U6,将 7 替换为 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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.