计算机中正数是按照原码存储的,负数是按照补码存储的
下面举例 1 和-1,按照8位存储。
:
正数:正数的原码,反码,补码都和原码一样,即正常的二进制表示。
负数:原码就是正常的二进制表示。反码就是原码的按位取反(符号位不变),补码是在反码的基础上+1。
1 | -1 | |
原码 | 0000 0001 | 1000 0001 |
反码 | 0000 0001 | 1111 1110 |
补码 | 0000 0001 | 1111 1111 |
1 + 1 = 2
0000 0001
0000 0001
0000 0010
用1的原码直接相加得到了0000 0010 = 2 和我们预期的结果是一致的。说明没问题
为什么负数用补码表示呢?
我们计算 1 - 1,我们可以转换成 1 +(-1)= 0 这里需要明白一个问题,在计算机内部其实只有加法器。其实减去一个数就相当于加上一个负数。
如果用 -1 的原码加的话:
0000 0001 = 1 的原码
1000 0001 = -1的原码
1000 0010 = -2 明显和我们的预期结果不一样,
为了解决原码减法的问题,就出现了反码,使用反码再来计算:
0000 0001 = 1 的反码
1111 1110 = -1 的反码
1111 1111 这是反码,转为原码就是1000 0000 即为-0;
我们都知道0不分正负,为了解决0的符号问提,就出现了补码,然后我们子啊用补码:
0000 0001 = 1 的补码
1111 1111 = -1 的补码
1 0000 0000 因为我们上面默认的是8位存储,超过了8位就舍去,剩下的是0000 0000 = 0,符合我们的预期结果0。
那问题来了,-0跑哪里去了?,-0即1000 0000 这里表示的-128,并且-128没有原码和反码,只有这个补码。
然后我们看一下-127的原码、反码、补码:原码: 1111 1111反码: 1000 0000补码: 1000 0001。
-127 -1 = -128,所以-127的补码-1应该也是-128的补码,即1000 0001 -1 = 1000 0000。因此1000 0000就是 -128的补码。
在一个字节8位中,如果用原码来表示值的大小范围,只能是 1111 1111 ~ 0111 1111,即-127~127 。但是,用补码的话可以表示的取值范围
设置127 — -128,正好是2^8,256个数。
因此,-0可以表示一个最低数。在8位二进制中它是1000 0000 ,在32位中,它就是 1000 0000 0000 0000 0000 0000 0000 0000 ,int的最
小值。(32位数值大小范围为 -2^31 ~ 2^31 -1)
总结:补码的存在解决了0的符号问题,同时统一了计算机的加减法运算。