[英]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. 如第一个输出所示,将0x80000000右移31位应得到0x00000001。 Why the output is different here when the variable
l
is shifted by 31 bits to the right? 当变量
l
向右移动31位时,为什么此处的输出不同?
Assuming the result of 假设结果
l = (x & (0x00000001 << (N_BITS - 1)));
is 0x80000000
(see below it is not guaranteed as the expression invokes undefined behavior). 为
0x80000000
(请参见下文,由于表达式会调用未定义的行为,因此无法保证)。
In two's complement system, 0x80000000
is a negative value ( INT_MIN
). 在二进制补码系统中,
0x80000000
是负值( INT_MIN
)。
l = l >> 31;
C says this >>
operation is implementation-defined. C表示此
>>
操作是实现定义的。 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."
(C11,6.5.7p4)“如果E1具有带符号的类型和负值,则结果值是实现定义的。”
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. "
(C11,6.5.7p4)“ E1 << E2的结果是E1左移E2位的位置;空位用零填充。如果E1具有无符号类型,则结果的值为E1×2 ^^ E2 ,以比结果类型中可表示的最大值大的模减少一个模, 如果E1具有带符号类型和非负值,并且E1×2 ^^ E2可在结果类型中表示,则为结果值;否则为行为未定义。 ”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.