天天看点

c++ int和unsignedint溢出原理分析

首先,我们要找到int的最大值,在climits头文件中有一个常量是INT_MAX表示int的最大值。

上溢:

/*by kzl*/
#include<iostream>
#include<climits>
using namespace std;

int main(){
    int n_max = INT_MAX;
    unsigned int un_max = n_max;
    cout<<"有符号整数最大值: "<<n_max<<endl;
    cout<<"无符号整数最大值: "<<un_max<<endl;
    cout<<"加一之后"<<endl;
    n_max = n_max + 1;
    un_max = un_max + 1;
    cout<<"有符号整数的值: "<<n_max<<endl;
    cout<<"无符号整数的值: "<<un_max<<endl;
return 0;
}
           

结果:

c++ int和unsignedint溢出原理分析
c++ int和unsignedint溢出原理分析

向下溢出:

/*by kzl*/
#include<iostream>
#include<climits>
using namespace std;


int main(){
    int n_max = 0;
    unsigned int un_max = 0;
    cout<<"有符号整数的值: "<<n_max<<endl;
    cout<<"无符号整数的值: "<<un_max<<endl;
    cout<<"减一之后"<<endl;
    n_max = n_max - 1;
    un_max = un_max - 1;
    cout<<"有符号整数的值: "<<n_max<<endl;
    cout<<"无符号整数的值: "<<un_max<<endl;
return 0;
}
           

结果:

c++ int和unsignedint溢出原理分析
c++ int和unsignedint溢出原理分析

向上溢出的原理(默认int是32位的):有符号位的Int第一位是符号位,所以其实际上只能存储31个有效位。当他的后31位全部是1的时候,就是int的最大值。

c++ int和unsignedint溢出原理分析

然后如果在加一,就变成了100000000000...(31个0)第一位符号位是1表示负数,然后后31位为0,表示负数的最小值为-2147483648.如果在加一,则数字为-2147483647.

无符号:因为无符号32位全部是有效位,所以其上限是4294967295,远远大于当前值,所以可以正常的加1.

向下溢出的原理:

无符号:一开始32位全部是0,然后减1,从前面位借位过来,所以32位全部被置为1,所以变成了他的最大值。

有符号:同理,32全部被置为1,但是由于第一位是符号位,所以只有后面31位有效,表示第2147483647小的负数,就是-1.

继续阅读