为什么向上移位int会产生负数?

我是位操作技巧的新手,我写了一个简单的代码,看看在单个数字上进行单位移位的输出。 2

 #include  int main(int argc, char *argv[]) { int num=2; do { std::cout<<num<<std::endl; num=num<<1;//Left shift by 1 bit. } while (num!=0); return 0; } 

输出如下。

 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 1073741824 -2147483648 

显然,连续向左移位1位,如上所述将导致零,但为什么计算机在终止循环之前输出负数(因为num变为零)?

但是,当我用unsigned int num=2替换int num=2 ,我得到相同的输出,除了最后一个数字是这个时间显示为正数,即2147483648而不是-2147483648

我在Ubuntu Linux上使用gcc编译器

那是因为int是有符号整数。 在二进制补码表示中 ,整数的符号由最高位确定。

一旦你将1移到最高(符号)位,它就会翻转为负数。

使用unsigned ,没有符号位。

 0x80000000 = -2147483648 for a signed 32-bit integer. 0x80000000 = 2147483648 for an unsigned 32-bit integer. 

编辑:

请注意,严格来说,有符号整数溢出是C / C ++中未定义的行为。 GCC在这方面的行为并不完全一致:

  • num = num << 1; 或者num <<= 1; 通常表现如上所述。
  • num += num;num *= 2; 实际上可能会进入GCC的无限循环 。

好问题! 答案很简单。

最大整数值为2^31-1 。 31(不是32)是有原因的 – 整数的最后一位用于确定它是正数还是负数。

如果你继续向左移动位,你最终会击中这一位并且它变为负数。

有关此内容的更多信息: http : //en.wikipedia.org/wiki/Signed_number_representations

一旦该位到达有符号(最高有效位)的符号位,它就会变为负数。