簡體   English   中英

有人可以解釋這個bitMask代碼是如何工作的嗎?

[英]Can someone explain how this bitMask code works?

這是我的合作伙伴提出的代碼,但出於某種原因,我無法抓住他,問他如何工作。 我現在經歷了很多次,似乎無法得到我想要得到的答案。

/**
 * bitMask - Generate a mask consisting of all 1's 
 *   lowbit and highbit
 *   Examples: bitMask(5,3) = 0x38
 *   Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
 *   If lowbit > highbit, then mask should be all 0's
 *   Legal ops: ! ~ & ^ | + << >>
 */
int bitMask(int highbit, int lowbit) {
   int i = ~0;
   return ~(i << highbit << 1) & (i << lowbit);
}

這個函數實際上是不正確的:對於highbitlowbit大值,它可能具有特定於實現的行為甚至是未定義的行為。 它應該使用並返回unsigned類型:

unsigned bitMask(int highbit, int lowbit) {
    unsigned i = ~0U;
    return ~(i << highbit << 1) & (i << lowbit);
}

以下是步驟:

  • i = ~0U; 將i設置為所有位1。

  • i << highbit將這些位i << highbit移位,在低位中插入highbit 0位。

  • i << highbit << 1為一個0位騰出空間。 不應該將此表達式簡化為i << (highbit + 1)因為如果highbit + 1變得大於或等於i類型中的位數,則這種位移是實現定義的。

  • ~(i << highbit << 1)補充了這個掩碼,創建了一個掩碼,其中highbit + 1位設置在低位,0位表示高位。

  • i << lowbit創建一個lowbit 0位掩碼, lowbit位置1。

  • ~(i << highbit << 1) & (i << lowbit)計算這兩個掩碼的交集,結果從位數lowbit到位數highbit包含1位,從lowbit有效位編號為0

例子:

  • bitMask(31, 0) - > 0xFFFFFFFF
  • bitMask(0, 0) - > 0x00000001
  • bitMask(31, 16) - > 0xFFFF0000
  • bitMask(15, 0) - > 0x0000FFFF

該編號方法用於硬件規范。 我個人更喜歡一種不同的方法,其中一個指定要跳過的位數和要設置的位數,更符合位域規范:

unsigned bitSpec(int start, int len) {
    return (~0U >> (32 - len)) << start;
}

和相同的例子:

  • bitSpec(0, 32) - > 0xFFFFFFFF
  • bitSpec(0, 1) - > 0x00000001
  • bitSpec(16, 16) - > 0xFFFF0000
  • bitSpec(0, 16) - > 0x0000FFFF

在您的情況下,根據您的函數附帶的描述,該函數正在執行您似乎打算執行的操作。 主要問題是您使用的是int而不是unsigned int 這將導致符號擴展問題。 (更不用說C中簽署的輪班缺乏定義)。

簡單轉換為unsigned將顯示它正在按預期運行:

簡短的例子:

#include <stdio.h>
#include <stdlib.h>

unsigned int bitMask (unsigned int highbit, unsigned int lowbit) {
    unsigned int i = ~0;
    return ~(i << highbit << 1) & (i << lowbit);
}

char *binstr (unsigned long n, unsigned char sz, unsigned char szs, char sep) {

    static char s[128 + 1] = {0};
    char *p = s + 128;
    unsigned char i;

    for (i = 0; i < sz; i++) {
        p--;
        if (i > 0 && szs > 0 && i % szs == 0)
            *p-- = sep;
        *p = (n >> i & 1) ? '1' : '0';
    }

    return p;
}

int main (int argc, char **argv) {

    unsigned high = argc > 1 ? (unsigned)strtoul (argv[1], NULL, 10) : 5;
    unsigned low  = argc > 2 ? (unsigned)strtoul (argv[2], NULL, 10) : 3;

    printf ("%s\n", binstr (bitMask (high, low), 32, 8, '-'));

    return 0;
}

產量

$ ./bin/bitmask
00000000-00000000-00000000-00111000

$ ./bin/bitmask 10 3
00000000-00000000-00000111-11111000

$ ./bin/bitmask 31 5
11111111-11111111-11111111-11100000

$ ./bin/bitmask 4 8
00000000-00000000-00000000-00000000

暫無
暫無

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

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