C ++整数溢出

时间:2015-03-24 14:38:25

标签: c++ integer-overflow

我刚刚开始自学C ++,并开始学习整数溢出。出于好奇,我写了一些测试,只是为了看看某些整数值会发生什么。

这是我的计划:

#include <iostream>

int main()
{
    int x(0);
    std::cout << x << std::endl;

    x = x + 2147483647;
    std::cout << x << std::endl;

    x = x + 1;
    std::cout << x << std::endl;
    std::cout << std::endl;

    unsigned int y(0);
    std::cout << y << std::endl;

    y = y + 4294967295;
    std::cout << y << std::endl;

    y = y + 1;
    std::cout << y << std::endl;
}

这是输出:

0
2147483647
-2147483648

0
4294967295
0

输出让我感到有些惊讶,我想知道是否有人可以解释为什么会发生这种情况,或者如果这些结果出乎意料的话,那就是预料到的;所以这可能只是我特定机器的结果。

4 个答案:

答案 0 :(得分:5)

有符号整数溢出是未定义的行为,而无符号整数溢出是明确定义的;价值包裹着。换句话说,该值以模除以2 ,其中是数据类型中的位数。由于您拥有32位int

  

4294967295 + 1 = 4294967296%2 32 = 0

在第二种情况下导致0。从语言的角度来看,第一种情况是未定义的。

但是,大多数实施都使用2's complement来实施signed integer types。使用2的补码实现的玩具,带符号的4位数据类型可用于解释在第一种情况下发生的事情。在这种类型

POS_MAX = 7 = 0111) 2

NEG_MAX = -8 = 1000) 2

该类型可以容纳2个 4 = 16个状态,8个正数(0到7)和8个负数(-1到-8)。

POS_MAX + 1 = 0111) 2 + 1) 2 = 1000) 2

由于设置了第一位,它是一个负数,为了找到实际值,反向进行二进制补码(减去1和翻转位)

1000) 2 - 1) 2 = 0111) 2

~0111) 2 = 1000) 2 = 8

因此最终值为-8。所有这些都不是由语言定义的,但这就是你的情况,特别是。

答案 1 :(得分:4)

整数(通常)采用32位表示。如果您有32位,则可以从0到2 31 -1进行寻址。即,

00000000000000000000000000000000
00000000000000000000000000000001
.
.
.
01111111111111111111111111111111
^-------------------------------
signed bit

0表示正数,1表示负数。

如果您向01111111111111111111111111111111添加1,则会得到10000000000000000000000000000000,即十进制的-2147483648。

使用无符号整数,没有符号位,事实上,它的数字可能是最大有符号整数的两倍。但是,当号码再次翻转时(即11111111111111111111111111111111 + 00000000000000000000000000000001),您只需回滚到00000000000000000000000000000000

为了更深入地理解,您可以查看two's complement,这是整数在计算机中的表示方式。

答案 2 :(得分:1)

Integer有两种类型。签名和未签名,传统上都是32位。

在第一种情况下,您使用的是签名的Integer。在这种情况下,1位保留用于符号,其余31位用于大小。在这种情况下,可以保存的最大数字是2 ^ 31 - 1 = 2147483647.向其中添加一个将影响最高有效位,将数字更改为负数。 (有关详细信息,请参阅Google 2的数字符号)。

在第二种情况下,您使用的是unsigned int,其中所有32位都保留为幅度。因此,存储的最大数量是2 ^ 32 - 1.添加一个将为零。 E. G.说我们有3位数系统,111 = 7.添加一个将使它成为1000,但是从它的3位系统,它将变为000 = 0

答案 3 :(得分:0)

阅读两个补充。基本上,一旦你达到处理器可以支持的最高整数并且你加1,它会通过打开&#34;符号&#34;来进入负数。位。