Human Cyborg Relations
Human Cyborg Relations

Reputation: 1244

Printing bit fields from integer

I'm supposed to extract 10 fields of given widths from a 32-bit integer.

For example, if the given width is 2, then I need to extract the 2 left-most bits of the integer and print their integer value.

Here is the code I have right now,

#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");
}

The output I'm getting right now is, 0000000004, which makes no sense to me at all.

Upvotes: 0

Views: 1678

Answers (2)

alvits
alvits

Reputation: 6758

You solution is an overkill, using left shift, right shift and masking. You can simplify it.

By using left shift and right shift only.

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

Now, let's see the output.

6 5 7 7 5 7 5 3 3 2

Upvotes: 2

Lionishy
Lionishy

Reputation: 309

The problem in extracting the bits originates in types mismatch. How are you expecting to extract, say, 28th bit from an unsigned integer multiplying to the 8-bit char?

So, first of all make the mask to be unsigned integer. Next, I believe you need to shift your mask to the 31-totalWidth, not totalWidth in mask = (1 << (L - R + 1) - 1) << totalWidth;. As you wrote: "2 left most".

Upvotes: 1

Related Questions