c++ - 为什么将 int 向上移位会产生负数?

标签 c++ c bit-manipulation bit-shift

我不熟悉位操作技巧,我编写了一个简单的代码来查看对单个数字进行单位移位的输出,即。 2

#include <iostream>
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是一个带符号的整数。在two's-complement representation , 整数的符号由最高位决定。

一旦您将 1 移到最高(符号)位,它就会变为负值。

当您使用 unsigned 时, 没有符号位。

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

编辑:

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

关于c++ - 为什么将 int 向上移位会产生负数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8371469/

相关文章:

c - 将 c 代码片段翻译为伪代码

c - XML 模式验证 - 将模式文件内容作为字符串而不是文件传递

c - 如何概括我的代码

c++ - Makefile 似乎忽略了标志。为什么?

c++ - 我可以在现代 Intel Core CPU 上测量分支预测失败吗?

c++ - Visual Studio 调用堆栈窗口不显示文件名

c - 使用 C/whatever 中的 ffmpeg 以编程方式捕获 X11 区域

lua - Lua 中的 "Bitwise AND"

python-3.x - python3 : How to get logical complement (negation) of a binary number, 例如。 '010' => '101' ?

c++ - 成员初始化器列表中的初始化