简体   繁体   English

右移按位操作时出现意外输出

[英]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.

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