产生的背景
计算机的硬件决定了,任何存储在计算机中的数据,本质都是以二进制码存储的。
根据冯·诺依曼提出的经典计算机体系结构框架,一台计算机由运算器、控制器、存储器、输入和输出设备组成。其中运算器只有加法运算器,没有减法运算器(一开始是有的,后来由于减法运算器硬件开销太大,被废除了)。
所以计算机中没办法直接做减法的,它的减法是通过加法实现的。现实世界中所有的减法也可以当成加法的,减去一个数可以看作加上这个数的相反数,但前提是要先有负数的概念,这就是为什么不得不引入一个符号位。符号位在内存中存放的最左边一位,如果该位为0,则说明该数为正;若为1,则说明该数为负。
而且从硬件的角度上看,只有正数加负数才算减法,正数与正数相加,负数与负数相加,其实都可以通过加法器直接相加。
原码、反码、补码的产生过程就是为了解决计算机做减法和引入符号位的问题。
什么是原码
是最简单的机器数表示法,最高位表示符号位,其他位存放该数对应的绝对值的二进制值。
以带符号位的四位二进制数为例:1010,最高位为1表示这是一个负数,其它三位010,即0 * 2^2+1 * 2^1+0 * 2^0=2,所以1010表示十进制数-2。
用原码进行运算:
0001 + 0010 = 0011 ,1 + 2 = 3
0000 + 1000 = 1000 ,0 + (-0) = -0
0001 + 1001 = 1010 ,1 + (-1) = -2
1001 + 1010 = 0011 , -1 + (-2) = 3
以上运算可以看出,原码进行计算时,两个正数相加是没有问题的。而正数与负数相加,或者负数与负数相加就会导致计算结果的错误,这都是符号位引起的问题。0分为+0和-0也是因为需要区分符号位。
什么是反码
正数的反码等于原码;负数的反码就是原码保留符号位外,其他按位取反。
原码的一个问题是一个数加上它的相反数结果不等于0,于是反码的设计思想就是为了解决这一点。既然一个负数是一个正数的相反数,那么用一个正数按位取反来表示负数。
以带符号位的四位二进制数为例:3是正数,反码与原码相同,则可以表示为0011;-3的原码是1011,符号位保持不变,低三位按位取反,所以-3的反码为1100。
试着用反码解决原码运算出错的问题:
0001 + 1001 -> 0001 + 1110 = 1111(反码) -> 1000(原码), 1 + (-1)= -0
1001 + 1010 -> 1110 + 1101 = 1011(反码) -> 1100(原码) , -1 + (-2) = -4
这样互为相反数的两个数相加结果正确了,但是负数相加还是有问题。
什么是补码
正数的补码等于原码,负数的补码等于它的反码+1
以带符号位的四位二进制数为例:3是正数,补码与原码相同,则可以表示为0011,-3的原码是1011,反码为1100,补码为1101。
试着用补码解决反码运算出错的问题:
1001 + 1010 -> 1111 + 1110 = 1101(补码)-> 1100(反码)-> 1011(原码),-1 + (-2) = -3
这样负数相加的问题就解决了,所以计算机中的运算都是以补码进行的。
总结
1. 原码的最高位为符号位,符号位为0表示正数,为1表示负数。其他位存放该数对应的绝对值的二进制值。
2. 正数的反码等于原码,负数的反码就是原码保留符号位外,其他按位取反。
3. 正数的补码等于原码,负数的补码等于它的反码+1。