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.