为什么我在做leftshift后得到-256?

时间:2017-05-22 15:01:08

标签: c bit-shift

我无法理解下面代码的输出。它输出为 -256

_.LookForRegistries()

2 个答案:

答案 0 :(得分:2)

首先,在您的平台char是一个签名类型,从-128127。在2's complement representation之后,正数从0x000x7f表示,从那里开始,负数开始。因此0x80为-128,0x81-127,依此类推,直至到达0xFF -1

在您的代码中,您将-1分配给变量c。当您对char进行位移时,它会被提升为int,因此您最终会以整数形式显示-1,这是(仅举例)0xFFFFFFFF如果int是32位。

当您向左移位负数时,最低有效位会被0填充,因此您最终得0xFFFFFF00-256

答案 1 :(得分:0)

使用Two's Complement计算机代表负数。声明char时,将分配一个8位的字节。如果变量已签名且其最高有效位为1,则它将是2^n位置的负值。

例如,char具有8位且其sigbit为1,0x80 = 1000 0000 = -2^8 = -128。将剩余位设置为1时,将添加每个2^n位的正值。查看有关数字here的二进制表示的更多信息。每个十六进制字符代表四位,在0xFF的情况下,您将c的八位设置为1。

char c = 0xFF; // 0xFF = 1111 1111 = -1

所以你有-128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1

当您预先形成左移c << x时,将c的位移到左x位,同时在移动时用零填充右边的位置。以下是@ legends2k之前的stackoverflow答案的解释。

  

E1的结果&lt;&lt; E2是E1左移E2位位置;腾出的位用零填充。如果E1具有无符号类型,则结果的值为E1×2E2,比结果类型中可表示的最大值减少一个模数。如果E1具有带符号类型和非负值,并且E1×2E2在结果类型中可表示,那么这就是结果值;否则,行为未定义。 reference

此外,当您预先换班时,您将c提升为int

  

ISO / IEC 9899:2011(C)

     

§6.5.7按位移位运算符

     

1183对每个操作数执行整数提升。

要在0xFF的意义上保留-1 char的值,在32位机器上,整数是4个字节,其位均为1,表示-1或0xFFFFFFFF

当您向左移8位时,(0xFFFFFFFF << 8) = 0xFFFFFF00 = -256