簡體   English   中英

按位運算和掩碼:返回掩碼中設置的原始變量的位值

[英]Bitwise operations and masks: return bit values of the original variable that are set in the mask

這是我第一次在這里想知道以前沒有問過同樣的問題,因此我必須自己問:)

我正在使用一個設備(不會深入探討,因為它現在無關緊要),我有兩個輸入,每個輸入的長度為 16 位。 第一個輸入具有后來需要的值,第二個具有我們想要找到第一個輸入值的“位置”。 讓我舉個例子:

編輯:澄清:掩碼可以是長度為 16 位且設置為 8 位的任何內容。 不僅有最低的兩個半字節集 (1),只是說明場景就這么簡單。

input:  0101 1011 0000 0111
mask:   0011 0011 0011 0011
output: 0001 0011 0000 0011

當掩碼設置為 1 時,機器需要返回輸入的值,無論是 1 還是 0,都沒有關系。 設備稍后會使用該值。

如上所述,我可以使用簡單的&找到解決方案,但這還不夠,因為我的硬件有其局限性,並且有資源需要保存。 如示例所示,掩碼可能只包含最多 8 位設置,因為電路板上的某些東西是互斥的,我希望並且可以讓我的輸出長度僅為 8 位:

output: xx01 xx11 xx00 xx11
saved to a variable as: 0111 0011

...我只是不知道怎么做。

那么我應該如何繼續,我應該在保存掩碼設置位的位置的數組上構建,然后從輸入中檢查值,還是有更有效的方法來做到這一點。 關於掃描值等並不重要,因為我可以處理它,目前我們可以將輸入和掩碼視為任何 16 位長整數。 在一小段代碼中,我使用了與之前二進制示例中使用的相同的模擬十進制值。

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
    uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
    uint8_t fi;             //Filtered inputs=input after masking, this one to be returned

    /*something needs to be done here*/

    return fi;              //With these inputs, this should be 115

    return 0;
}

只需進行一些移位和掩碼即可將您想要的所有位或-ed 組合成一個 8 位值:

#include <stdint.h>
#include <stdio.h>

int main(void) {
  uint16_t input = 0b0101101100000111;

  // Extract the low 2 bits of each nybble via shifting and masking
  uint8_t fi = (input & 0b11) | ((input >> 2) & 0b1100) | 
    ((input >> 4) & 0b11'0000) | ((input >> 6) & 0b1100'0000);

  printf("%#010b\n", fi); // 0b01110011

  return 0;
}

使用 C23 功能,如二進制文字、' 作為數字分隔符和%b格式用於說明目的,因為我們正在使用單個位。 對於不支持前沿的編譯器,掩碼值的十六進制版本分別為0x30xC0x300xC0

最簡單的方法:

    #include <stdio.h>
    #include <stdint.h>

    int main()
    {
        uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
        uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
        uint8_t fi;             //Filtered inputs=input after masking, this one to be returned
     
        /*something needs to be done here*/
        uint16_t temp = input & mask;
        uint8_t np0, np1, np2, np3;
        np0 = temp &0x03;
        np1 = (temp >> 4) & 0x03;
        np2 = (temp >> 8) & 0x03;
        np3 = (temp >> 12) & 0x03;
        
        fi = np0 | (np1 << 2) | (np2 << 4) | (np3 << 6);

        return fi;              //With these inputs, this should be 115

        return 0;
    }

有點復雜但可能更快:#include <stdio.h> #include <stdint.h>

    int main()
    {
        uint16_t input=23303;   //1st input, gives the 1s and 0s to be extracted
        uint16_t mask=13107;    //2nd input, defines the locations of needed 1s and 0s
        uint8_t fi;             //Filtered inputs=input after masking, this one to be returned
     
        /*something needs to be done here*/
        
        fi = (temp &0x03) | ((temp >> 2) & 0x0C) | ((temp >> 4) & 0x30) | ((temp >> 6) & 0xC0);

        return fi;              //With these inputs, this should be 115

        return 0;
    }

掩碼可以是長度為 16 位且設置為 8 位的任何內容。 ...

遍歷input & mask的結果,並在每次迭代中檢查掩碼位是否設置。 如果它的設置比在8位結果中設置相應的位。

你可以做:

#include <stdio.h>
#include <inttypes.h>

int main (void) {
    uint16_t input = 23303;
    uint16_t mask = 13107;
    uint8_t fi = 0;
    uint16_t res = input & mask;
    
    for (unsigned int x = 0, c = 0; res; res >>= 1, ++x) {
        if ((mask >> x) & 0x1) {
            if (res & 0x1) {
                fi |= 0x1 << c;
            } 
            c++;
        }
    }

    printf ("fi : %" PRIu8 "\n", fi);
    return 0;
}

輸出:

% ./a.out
fi : 115

嘗試使用長度為16位且設置為8位的其他掩碼值的上述解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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