计算机底层为什么要用补码,而不用原码或反码?

计算机是不能直接做减法运算的,因为普通电脑硬件中没有减法器,但负数的存在可以用加法器转换成减法。但也就是因为负数的存在,原码和反码都不适合做计算,为什么呢?首先我们得知道什么是原码,什么是补码还有什么是反码。

原码

原码是对自然正数(包括0)的二进制编码,正数在计算机中直接用原码进行存储。

整数的正负属性使用字节的最高位来区分,也就是从左数第一个数字来表示正负,0为正,1为负。

10进制的3,二进制就是00000011
10进制的-3,二进制就是10000011
举例 1-1 = 0
转成原码后进行计算:
00000001 + 10000001 = 10000010
10000010 是-2,计算错误,所以原码不能做计算。

反码

反码是除符号位(可以理解成左边第一个字符)不变外,其余按位取反,这种方式对负数生效,正数取反还是保持原码不变。计算机并不存储反码

为什么需要反码?

计算机是不能直接做减法运算的,因为普通电脑硬件中没有减法器,但我们可以用负数来做减法

反码的作用就相当于数学中的负:3-5 =3+[-5]=[-2]

  1. 正数的反码保持原码不变:3=[0x0000011]
  2. 负数除正负符号位外,全部取反(0变1,1变0):-5=1x0000101 取反=[1x1111010]
  3. 于是3+[-5]=[-2]的计算过程为:[0x0000011]+[1x1111010]=[1x11111101]
举例 1-1 = 0
00000001 + 11111110 = 11111111
此时的8个1是反码,转成原码,就是10000000,也就是 - 0,-0和0也算正确。
但是又会出来一个问题:0就有两种表示方法:10000000或00000000
由于计算机是严谨的学术,这种情况在计算机中被认为是不合理的,所以反码不适合做计算。

补码

正数的补码是其原码本身,而负数的补码是先求反码,然后再让反码加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

  1. 正数的补码保持原码不变:3={0x0000011}
  2. 负数先求反码,然后再加1:-5=[1x1111010]+1={1x1111011}
  3. 于是3+{-5}={-2}的计算过程为:{0x0000011}+{1x1111011}={1x1111110}

所以,负数在计算机中使用补码进行存储,正数原码进行储存,在计算机的世界里,0是正数

 

Reference:

  1. https://www.jianshu.com/p/f810fd0c786d
posted @ 2022-03-19 23:35  cancantrbl  阅读(938)  评论(1编辑  收藏  举报