LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Inconsistent bitwise operator behaviour in C (http://www.linuxquestions.org/questions/programming-9/inconsistent-bitwise-operator-behaviour-in-c-526518/)

oneandoneis2 02-07-2007 04:24 PM

Inconsistent bitwise operator behaviour in C
 
I'm working through K&R to learn C, and I've reached the bit on bitwise operators. I stumbled onto this issue whilst trying to accomplish something else, and have been trying to understand what's going on ever since.

Here's two bits of code. They both output the same numbers by doing left-shift bitwise operations, starting from ~0

The first method, however, shifts to zero from -2147483648; while the second method shifts to -1 from the same number. And I don't understand why.

Code:

int main(void)
{
        int i = ~0;
        int j = 0;

        while (j != 33) {
                i <<= 1;
                printf("%d: %d\n", j++, i);
        }
        return 0;
}

Code:

int main(void)
{
        int i = 0;

        while (i < 33)
                printf("%d: %d\n", i, (~0 << i++));
        return 0;
}

Any clarification would be appreciated!

Dark_Helmet 02-07-2007 04:47 PM

There's no inconsistency that I can see. The difference lies in how the loops execute.

In your first example, the variable i is modified (shifted left by one) before the first printf call is made - you never see the initial value of i displayed.

In your second example, you see the initial value (~0) because your loop starts with i=0. Therefore, the first time the printf call is made, ~0 is shifted left 0 times (i.e. left unchanged). Only after that statement executes does i's value increment by one (which later causes "real" shifting to occur).

jtshaw 02-07-2007 05:08 PM

My memory of this isn't great but if I'm right it actually isn't inconsistent.

In example 1 you are taking ~0 (0xFFFFFFF) in our case and shifting it by some constant. The single shift operator in C does wrap indefinitely. In example 2, your starting with ~0 (0xFFFFFFF) and removing 1 bit each time. Eventually you get to 0 and no matter how many bytes you shift 0x00000000 your going to end up with 0.

tuxdev 02-07-2007 05:09 PM

Dark_Helment: His blog has a better description of his confusion. When he does the shifting one at a time, it converges to zero, but when he does the shifting all at once, it loops around with a period of 32.

Shifting by a negative number or a number greater than or equal to the data width is undefined in C. GCC just has a convienient definition for the undefined behaviour. Consider less-sane values to shift by for the bit rotation K&R exercise.

oneandoneis2 02-08-2007 03:20 AM

Quote:

Originally Posted by tuxdev
Shifting by a negative number or a number greater than or equal to the data width is undefined in C. GCC just has a convienient definition for the undefined behaviour.

Ah! That would explain it. Maybe I should've bought that book on GCC after all..

Cheers!


All times are GMT -5. The time now is 12:29 AM.