32位的int 的范围为 -2^31 ~ 2^31-1。以下讨论的均是32位的有符号整数,最高位为符号位。

int main(){
    int s1 = 0x80000000;
    int s2 = 0x7fffffff;
    int s3 = 0xffffffff;
    cout << "int最小值" << s1 << endl;
    cout << "int最大值" << s2 << endl;
    cout << "注意:" << s3<<endl;
    system("pause");
}

求源码的补码为 :

(1)正数的补码和原码相同

(2)负数的补码=保持最高的符号位不变,其余位取反+1

但是

int s1=0x 8000 0000和 int s1=8这种方式有所区别:

计算机中存的是补码:

所以对于

int s1=8 这种方式,首先求8的补码存储到计算机中,然后输出的时候再还原回来。

然而对于

in s1= 0x ffff ffff 计算机中直接存的就是 0x ffff ffff 并不需要求 0x ffff ffff的补码,0x fffff ffff是以补码的形式直接存储到计算机中的。

因此对于

int s1= 0x ffff ffff,计算机中存储的是 0x ffff ffff ,输出的时候,需要将其还原回来

注意计算机存储的是0x ffff ffff是以补码的形式存储的,因此输出的是必须再还原回来:

0x ffff ffff的补码是  0x 8000 0001 ,最高位是符号位,因此输出的是-1

int的最小值在计算机中存储的为何存储的是0x 8000 0000 呢?(注意最高位的符号位不参与运算,相当于标志位)

因为 输出的时候 对 0x 8000 0000 取补码,注意最高位是符号位,不参与运算, 因此对于剩下的31位,  0x 000 0000 取反加1后得到的是 0x 8000 0000

和最高位的符号位,加起来是 0x 1 8000 0000 溢出了,截取1位得到的是 0x 8000 0000 是-0 但是 已经有0的存储方式了,是0x 0000 0000不需要有-0这种的存储方式,因此虽然截取掉了溢出的位,但是实际计算了最高位,这里是计算机为了表示更小的数做的特殊处理,因此实际上这里 表示的 是 0x 1 8000 0000而不是 0x 8000 0000,那 0x 1 8000 0000的最高位是 1表示负数,0x 8000 0000 的值是 2^31,合起来表示的就是 -2^31.