从整数打印位字段

时间:2017-02-15 02:52:50

标签: c bit-manipulation

我应该从32位整数中提取10个给定宽度的字段。

例如,如果给定宽度为2,那么我需要提取整数的最左边2位并打印它们的整数值。

这是我现在的代码,

#include <stdio.h>

void printAnswer(int width[]);

int main(){
    int width[10] = {3, 4, 4, 3, 3, 4, 4, 3, 2, 2};
    printAnswer(width);
}

void printAnswer(int width[]){
    unsigned int value = 0xCAFEBABE;
    char mask;
    int totalWidth = 0;
    int L; // left
    int R; // right

    for (int i = 0; i < 10; i++){
        L = 31 - totalWidth; // left end of width
        R = L - width[i]; // right end of width
        totalWidth = totalWidth + width[i];

        // creating a mask to capture bits in range
        mask = (1 << (L - R + 1) - 1) << totalWidth;

        printf("%d ", (value & mask) >> totalWidth);

    }

    printf("\n");
}

我现在得到的输出是0000000004,这对我来说毫无意义。

2 个答案:

答案 0 :(得分:2)

你的解决方案是一种矫枉过正,使用左移,右移和遮挡。你可以简化它。

仅使用左移和右移。

void printAnswer(int width[]){
    unsigned int value = 0xCAFEBABE, masked;
    int totalWidth = 0;

    for (int i = 0; i < 10; i++){
        masked = value << totalWidth; //get rid of the unwanted left bits
        totalWidth += width[i];
        masked >>= (32 - width[i]); //move the needed bits to the right
        printf("%u ", masked);
    }
    printf("\n");
}

现在,让我们看一下输出。

6 5 7 7 5 7 5 3 3 2

答案 1 :(得分:1)

提取位的问题源于类型不匹配。 你是如何期望从无符号整数中提取第28位乘以8位字符?

因此,首先使掩码成为无符号整数。 接下来,我相信你需要将掩码移到 31-totalWidth ,而不是mask = (1 << (L - R + 1) - 1) << totalWidth;中的totalWidth。正如你写的:“最左边的2”。