简体   繁体   中英

Unexpected Output in right shift bitwise operation

int main()
{

    int x = 0xff0000ff;
    int N_BITS = sizeof (int) * 8;  /* 32 */
    int l = 0x0;

    printf ("Right shift expected result: %x\n", 0x80000000 >> (31));

    l = (x & (0x00000001 << (N_BITS - 1)));
    printf ("l = %x\n", l);

    /* Right Shift l by 31 bits */
    l = l >> 31;
    printf ("l after right shift by 31 bits: %x\n", l);
}
~              

Output:

Right shift expected result: 1
l = 80000000
l after right shift by 31 bits: ffffffff

~
The right shift of 0x80000000 by 31 bits should result in 0x00000001 as shown in the very first output. Why the output is different here when the variable l is shifted by 31 bits to the right?

Assuming the result of

l = (x & (0x00000001 << (N_BITS - 1)));

is 0x80000000 (see below it is not guaranteed as the expression invokes undefined behavior).

In two's complement system, 0x80000000 is a negative value ( INT_MIN ).

l = l >> 31;

C says this >> operation is implementation-defined. In your system it performs sign extension: the sign bit is propagated.

(C11, 6.5.7p4) "If E1 has a signed type and a negative value, the resulting value is implementation-defined."

Finally on why:

0x000001 << (N_BITS - 1)

invokes undefined behavior.

From the horse mouth (emphasis mine):

(C11, 6.5.7p4) "The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2^^E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2^^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined. "

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM