计算机底层为什么要用补码,而不用原码或反码?
计算机是不能直接做减法运算的,因为普通电脑硬件中没有减法器,但负数的存在可以用加法器转换成减法。但也就是因为负数的存在,原码和反码都不适合做计算,为什么呢?首先我们得知道什么是原码,什么是补码还有什么是反码。
原码
原码是对自然正数(包括0)的二进制编码,正数在计算机中直接用原码进行存储。
整数的正负属性使用字节的最高位来区分,也就是从左数第一个数字来表示正负,0为正,1为负。
10进制的3,二进制就是00000011 10进制的-3,二进制就是10000011
反码
反码是除符号位(可以理解成左边第一个字符)不变外,其余按位取反,这种方式对负数生效,正数取反还是保持原码不变。计算机并不存储反码
为什么需要反码?
计算机是不能直接做减法运算的,因为普通电脑硬件中没有减法器,但我们可以用负数来做减法
反码的作用就相当于数学中的负:3-5 =3+[-5]=[-2]
- 正数的反码保持原码不变:3=[0x0000011]
- 负数除正负符号位外,全部取反(0变1,1变0):-5=1x0000101 取反=[1x1111010]
- 于是3+[-5]=[-2]的计算过程为:[0x0000011]+[1x1111010]=[1x11111101]
补码
正数的补码是其原码本身,而负数的补码是先求反码,然后再让反码加1。
为什么需要补码?
因为“0”这个特殊数字的存在。
8位二进制反码表示的正数范围: +0 ~ +127,负数范围: -127 ~ -0
但是,其中有两个特殊的编码会出现:
[0_0000000]=+0 (反码)
[1_1111111]=-0 (反码)
对于计算机来说,+0和-0都代表0了,这是绝对不行的,因为任何数字都只能有1个编码。于是补码出现了,把0当成正数,也即+0,这样0的编码就变成:0_0000000。那8位二进制表示的正数范围仍然是: +0 ~ +127。而负数则为整体向后“挪动1位”(即反码+1):只要将8位二进制表示的负数范围从:-127 ~ -0变成:-128 ~ -1,就能成功解决问题。 {1_1111111}编码就不再表示-0,而变成了-1。顺着推,最小的编码{1_0000000}就是-128
- 正数的补码保持原码不变:3={0x0000011}
- 负数先求反码,然后再加1:-5=[1x1111010]+1={1x1111011}
- 于是3+{-5}={-2}的计算过程为:{0x0000011}+{1x1111011}={1x1111110}
所以,负数在计算机中使用补码进行存储,正数原码进行储存,在计算机的世界里,0是正数
Reference:
- https://www.jianshu.com/p/f810fd0c786d