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.