簡體   English   中英

c 中的位操作和屏蔽

[英]Bit manipulation and masking in c

我正在處理一些 c 問題。 我有一個進程需要執行並且有位操作。 我有 2 個 uint8 類型的變量,例如uint8 bit_Part1uint8 bit_Part2 (每個為 U8)。 我想為這些變量添加值,一個是U4 ,另一個是U6 ,如U4_part1U6_part2 ,還有一個 boolean 值Bool_Part3我想將它們放入這些uint8 bit_Part1uint8 bit_Part2結構中,如下所示

在此處輸入圖像描述

到目前為止,我嘗試像這樣移動:

它的偽代碼:

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);

這是我希望看到的示例:

如果 U4_part1=0111,U6_Part2=001111,Bool_Part3=1(真)

那么預期的結果是:bit_Part1 & uint8 bit_Part2 都將包含數據 -> 00000|1|00||1111|0111

(注意我添加了 | 只是為了數據之間的分離 || 是為了分離 uint8 bit_Part1 和 uint8 bit_Part2)。

uint8中的附加值bit_Part2用0填充,對比上圖(&U4表示4位的值,U6表示6位的值)

我該怎么做?

更新:

我再次嘗試過的東西:

 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;

如果Bool_Part3有一些 integer 類型,你正在調用 Boolean 即使它不是標准的_Boolbool (在<stdbool.h>中聲明)類型並且可能有一個不是 0 或 1 的值,那么一個適當的方法來確保 0 或在結果中插入 1 是將其轉換為_Bool ,如下所示:

uint16_t temp = (_Bool) Bool_Part3 << 10 …

雖然您可以使用其他習語,例如!!Bool_Part3 ,但強制轉換的優點是可以顯式表達所需的操作,轉換為 0 或 1。(雖然 30 年前的程序員不得不在 C 中使用各種變通方法,但沒有理由以人們幾十年前現代表達方式可用時的方式來編程 kludges。)

筆記:

  • uint8_tuint16_t<stdint.h>中聲明。
  • 為了說明和均勻性,顯示了零位移。 它們可以被省略。

我會建議沿着這些思路:

#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;

我不知道這里所有變量的類型,或者是否存在設置其他位的可能性,例如U6_part2的六位范圍之外。 屏蔽可防止錯誤設置的雜散位傳播到生成的bit_Part1bit_Part2變量中。

我單獨處理了 boolean,因為 boolean 在很多 C 代碼中,包括您所寫的摘錄,是一個 integer(只有更新的 C 標准修改了這個,很多 C 代碼不使用新的 bool 定義); 任何非零值都算作“真”。 例如,如果您將Bool_Part3設置為 0xFFF0 並進入這段代碼,您當然不希望將它與結果進行“或”運算。 即使你把它屏蔽到最低位,你也可能得不到正確的結果。

這是使用 union 的另一種方法。 只需將 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM