不管是计算机导论还是计算机组成原理都会讲这三个名词:原码、反码、补码
先来看看定义:
原码:是最简单的机器数表示法。用最高位表示符号位,‘1’表示负号,‘0’表示正号。其他位存放该数的二进制的绝对值。
反码:正数的反码还是等于原码、负数的反码就是他的原码除符号位外,按位取反。
补码:正数的补码等于他的原码 负数的补码等于反码+1。
首先,原码很好理解,因为我们计算机要保存正数与负数,总是需要一位来保存符号。
可是呢,我们现在计算机都是用补码来保存数,那么为什么要用补码来保存呢?
主要是为了解决减法的问题,计算机内部为了简化构造,只有加法器,并没有减法器,也就是说不管你是做加法、还是减法都是用加法器。
首先,我们来看如果用原码,是否能满足无论加法、减法都用加法器呢?
0011+1001=1100 3+(-1)
显然是无法满足的
我们再来看下补码:
0011 补码:0011 1001 补码:1111
相加:0010 结果为2
是不是很神奇?为什么能直接相加呢?而且还是带着符号位直接加
我们先来看下生活中的时钟,如果现在是六点钟,如果我想知道两点钟之前是几点,那么直接算的话就是六点减去两点是四点,还有一种就是往前加十点,算出来也是四点。这就是因为我们到11点再加1点就又回到0点的特性。也就是说-2,相当于+10。
那这跟我们的补码有什么关系呢?
因为我们的计算机位数是有限的,超过限度就会溢出,而这个特性就和我们的时钟差不多了。
比如我们计算机现在是4位。从0000开始到1111可以表示2^4个数,如果1111再加一就又回到0000,这是不是和时钟一样呢?
也就是说这个范围从0开始到15,再加1就又变成0了。
所以在这0~15的空间里面你想要回退两个相当于前进14格
用二进制表示就是从0000~1111,在这个范围内如果一个数加上一个负数,就只需要加上这个数全部取反再加1(取反与原来相加等于15,也就是说(15-原来的数)+1)等价16-原来的数)。
这样看来我们的范围就是16个数,我们还要一位符号位来表示正负。
0000:0
0001:1
0010:2
0011:3
0100:4
0101:5
0110:6
0111:7
1000:-8
1001:-7
1010:-6
1011:-5
1100:-4
1101:-3
1110:-2
1111:-1
例如:3-2
在刚才的体系中的位置是:0011,它需要后退两格,所以加上0010全部取反加一等于1110,得0001。刚好是我们要的结果,
而-2的补码是符号位不变,其余取反加一,所以1010->1110,和我们刚求得的一样。
那如果是加呢 例如:3+2
0011+0010=0101 正数的补码又是不变的
所以设计很巧妙