Reading and changing bits in C uint32_t

codeoverflow picture codeoverflow · Nov 15, 2013 · Viewed 7k times · Source

I am using this code

int get_bit(int n, int bitnr) {
int mask = 1 << bitnr;
int masked_n = n & mask;
int thebit = masked_n >> bitnr;
return thebit;
}

void printbits(uint32_t bits) {
    int i;
    for (i = 0; i < 32; i++)
        printf("%d", get_bit(bits, i));
    printf("\n");
}

to get and print the bits of a uint32_t, and in another function this code

uint32_t bits= 0;
bits|= 1<< 0;

to change the most significant bit (left-most) from 0 to 1.

the problem is when printing bits using the printbits function, it prints them right, but when using printf("%#x", bits); I'm getting the hex value of the bits as if they are read from right to left!

so the printbits gives me '10000000000000000000000000000000' but the hex value printed is the value of '00000000000000000000000000000001'.

Help appreciated

Answer

Maxime Ch&#233;ramy picture Maxime Chéramy · Nov 15, 2013

 Changing the Most significant bit:

This line:

bits |= 1<< 0;

changes the least significant bit (LSB). 1 << 0 equals 1, which is not very significant :).

But, if you do:

bits |= 1 << 31;

or

bits |= 0x80000000;

You would actually change the most significant bit (MSB).

Printing the number in binary:

Your code is actually printing the number from right to left. You must change your loop to decrement.

for (i = 31; i >= 0; i--)

And if printing in the wrong way is fine for you (who knows...), try this:

uint32_t n = 41;
while (n) {
    printf("%d", n & 1);
    n >>= 1;
}

This can be easily adapted to print in the correct way using a recursive function:

void printbits(uint32_t n) {
    if (n) {
        printbits(n >> 1);
        printf("%d", n & 1);
    }
}

This algorithm works for any base with minor modifications.