views:

276

answers:

5

I'm rather ashamed to admit that I don't know as much about bits and bit manipulation as I probably should. I tried to fix that this weekend by writing some 'reverse the order of bits' and 'count the ON bits' functions. I took an example from here but when I implemented it as below, I found I had to be looping while < 29. If I loop while < 32 (as in the example) Then when I try to print the integer (using a printBits function i've written) I seem to be missing the first 3 bits. This makes no sense to me, can someone help me out?

Thanks for everyone's help, I've added comments to show changes I've made.

int reverse(int n)
{
    int r = 0;
    int i = 0;
    for(i = 0; i < 29; i++) //Should be i < 32
    {
        r = (r << 1) + (n & 1); //| instead of + to make it obvious I'm handling bits
        n >>=1;
    }

    return r;
}

Here is my printBits function:

void printBits(int n)
{
    int mask = 0X10000000; //unsigned int mask = 0X80000000;
    while (mask)
    {
        if (mask & n)
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
        mask >>= 1;
    }
    printf("\n");
}

And a working? reverse function

int reverse2(int n)
{
    int r = n;
    int s = sizeof(n) * 7; // int s = (sizeof(n) * 8) -1

    for (n >>= 1; n; n >>=1)
    {
        r <<=1;
        r |= n & 1;
        s--;


    r <<= s;
    return r;
}
+2  A: 

Instead of +, you should use | (bitwise or). And you should use < 32.

sblom
`+` and `|` will give the same results here.
interjay
`+` or `|` makes no difference here, and `+` is probably clearer, so why use `|`?
Chris Dodd
@Chris Dodd: `|` is clearer. You're dealing with bits, not arithmetics. So use the operators designed for bit manipulation.
Wallacoloo
I agree that it should be | but it should work fine with +
MK
You should use `|` to emphasize that your performing bit-wise operations.
Dale Hagglund
I still think `+` is clearer as you're adding a single bit, not doing a bitwise operation on the entire word
Chris Dodd
+1  A: 

As written, this will reverse the lower 29 bits of n into r. The top three bits of n will be left in n (shifted down 29 bits) and not returned.

I would suspect a problem with your printBits function if you see something else.

edit

Your printBits function prints the lower 29 bits of n, so it all makes sense.

Chris Dodd
+3  A: 

Print Bits is wrong, its 0x80000000 not 0x10000000.

>>> bin (0x80000000)  
'0b10000000000000000000000000000000'  
>>> bin (0x10000000)  
'0b10000000000000000000000000000'

See 0x1... doesnt set the highest bit.

evilpie
+5  A: 
int mask = 0X10000000;

puts a 1 in bit 28. You want 0X80000000.

Potatoswatter
+3  A: 

You have:

int mask = 0x10000000;

There are two problems here. You don't have the high bit set, and if you did, it still (probably) wouldn't work, as your compiler would be using arithmetic shift on a signed int.

You want to change your mask to:

unsigned int mask = 0x80000000;

For arithmetic shift, shifting 0x80000000 right will never become zero, as the sign bit will be magically extended into the other bits. See here for more details on arithmetic shift.

spong