int整型判断溢出问题

转自:https://www.huaweicloud.com/articles/64e2a426a2d4fe45b7be305791fe2839.html

1.表示范围

https://blog.csdn.net/u013760665/article/details/98520702

正整数用原码表示,负整数用补码表示。

-2^31 - 2^31-1
-2147483648 - 2147483647

-2^31二进制码为:

负整数在内存中的32位最大可以表示为:原码:1111 1111 | 1111 1111 | 1111 1111 | 1111 1111 ,即-(2^31-1)=-2147483647。但是却是从-2147483648开始,可以认为是-0让了一位,因为已经有0了。

那么转换为补码之后就是全0,就是-0,当这个最小负整数的补码除符号位外全是0的时候,就是-0的原码了,所以-0是最小的那个数,也就是-2147483648,但其实这个数在内存中并不存在原码,这个补码也不是真正的补码。

2*31-1二进制码为:0111 1111 | 1111 1111 | 1111 1111 | 1111 1111

那么很明显了,2*31-1+1,使得二进制位进1,那么就会变成int_MIN,也就是1+全0,这个在内存中对应的就是--2147483648。

实验:

#include<iostream> 
using namespace std;
int main()
{
    int i=2147483647;
    int j=2147483648;
    int k=2147483649;
    cout<<i<<endl;
    cout<<j<<endl;
    cout<<k<<endl;
    return 0;
}

输出:

int整型判断溢出问题

 

 正整数超出2147483647范围后出现了循环取值的现象,也就是2147483648溢出后回到了最小负整数-2147483648,2147483649溢出后变成了-2147483648+1=-2147483647,依次类推。

2147483649可以表示为-2147483648+1,1000 0000 | 0000 0000 | 0000 0000 | 0000 0000 + 0000 0000 | 0000 0000 | 0000 0000 | 0000 0001 = 1000 0000 | 0000 0000 | 0000 0000 | 0000 0001【就相当于加上正值了,继续做运算】
所以int整型溢出后可以用这样的方式类推。

2.判断一个正数在运算过程中是否溢出?

int temp = res * 10 + (chars[i] - '0');//temp为计算中的不断增大的正数
//如果temp发生溢出,>2^31-1,那么就会变为负数,下面的判断中左边为负数,右边为正数,所以不相等
//如果没有溢出,那么就是正常地相等
if (temp / 10 != res) return sign == 1? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = temp;

 

上一篇:《C++入门经典(第6版)》——1.4 总结


下一篇:《软件建模与设计: UML、用例、模式和软件体系结构》一一1.3 软件体系结构设计