原码、反码、补码的产生及原理

第一个出现的机器码是二进制码,它们没有正负之分,只有单的数字。
如果我们给它们分配8位内存(8bit)的限制去存放他们,是下面这个样子的


  但是在生活中为了表示”欠别人钱”这个概念,就从无符号数中划分出了“正数”和“负数”
而为了表示正与负数,人们发明了“原码“,把生活中应该有的正负概念原原本本的表示出来
把最左边的第一位腾出位置,存放符号,正用 0表示,负用1表示 


  这确实方便了人们的理解,但是却苦了计算机。我们希望1-1是0,但是计算机只能算出0000 0001 +1000 0001=1000 0010(-2) ,这不是我们想要的结果。而且这里还有一个问题,在原码中0有两种表示方式 +0 和-0而人脑可以知道第一位是符号位, 在计算的时候我们会根据符号位, 选择对真值区域的加减. . 但是对于计算机很难,于是就出现了一种计算机,里面包含了计算数值和识别符号位两种电路,但是这样的硬件设计成本太高,因而被淘汰了。

  所以人们想出一种方法使得符号位也参与运算。我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.于是人们开始探索 将符号位参与运算, 并且只保留加法的方法。

那么如何将减法运算变为加法运算呢?我们知道,减去一个正数等于加上一个负数:a-b=a+(-b)。现在的问题就变成了如何用一个正数c来代替负数-b参与运算。为了解决“减法”的问题,在“原码”的基础上,人们发明了“反码”“反码”的编码方式是用来处理负数的,即负数二进制原码的符号位置不变,其余位置相反。


计算十进制的表达式: 1-1=01 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上.虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0. 人们总是精益求精,希望只有一个0,接着就发明了补码。

而补码的计算就涉及到了同余的数学原理,可以利用时钟的表盘来理解。

任何有限的计数系统都有一个确定的模。如时钟的模是12(即只有一个位的十二进制系统,要是再加一个大钟,使小钟转一周大钟加一刻度,就是有两个位的十二进制系统),再比如8位计算机的模是2^8=256D=2*10^8B(每一位也可以单独看做一个模为2的计数系统)。

 对同一计数系统中的数量可以定义运算如相加,但运算结果超出预设位数时,就要发生溢出,这个溢出其实就是模,如果进位没有被另一个计数系统接受,结果看似“失真”,本质上是进入了“第二次循环(所以模是不可能达到的,如8位计算机的模是2^8=1 0000 0000 这是九位数,是八位数不可能达到的,八位最大数是1111 1111,再加1就溢出了,也就是模)”。

以时钟系统为例:8+7=15D=13(十二进制)>10(十二进制),进位1溢出丢失(除非用另一个时钟记录),在表盘上(即时钟计数系统中)呈现为3,而8-5=8+(-5)=3也得到了相同结果。

因此我们在有限的计数系统中可以定义一个概念“补数”。正数补数即为本身,负数A【补】=模-绝对值(A)。上例-5对12的补数就是10-5=7(注意这是十二进制里的运算)。一个数加上另一个数(可以是正数也可以是负数),结果等于加上这个数的补数,若有进位则舍弃进位。这里的舍弃进位,一点也不唐突,舍弃的,就是系统的模,也就是时钟的一整圈!这本质上,是因为所有有限模的计数系统都可以看做一个“环”或者“钟”,下面再对计算机的8位运算进行说明。

在8位计算机中,八位二进制码可以表示256个无符号整数,范围是0~255,这其实由两个范围组成:0~127  以及  128~255 。 二进制表示即为0000 0000~0111 1111   1000 0000~1111 1111  。为了达到用正数代替表示负数进行运算的目的,利用模的原理,我们以256为模,-1(1000 0001)的补数是255(1111 1111),-2(1000 0010)的补数是254(1111 1110)…..-128(1000 0000)的补数是128(1000 0000)。因此我们设计一种新的编码方式,以255作为-1的补码、254作为-2的补码(即用128~255作为补码来表示原码的-128~-1)……进行运算和储存,这就达到了正数代替负数进行运算的目的,而由于模计算的性质,溢出了之后舍弃,其实是舍弃了模,也就是表盘的一圈。


因此!所有补码都没有符号位!!!!!!!这只是因为发现负数原码对应的补码的最高位都是1,而正数对应的补码最高位都是0,所以为了方便人们理解所代表原码的正负而人为地将最高位和正负联系起来(这也是很多人所说的带符号位运算,其实是没有理解补码的真谛)。补码数字实际是按照无符号八位二进制数进行运算(因此,八进制补码的模2^8=1 0000 0000=256,补码的范围0~255,这其实由两个范围组成:0~127   128~255  分别对应着原码的0~127  -128~-1 )  二进制表示即为0000 0000~0111 1111   10000000~1111 1111  。而在补码中,不存在负数(负数被转换为相应的补码,补码这串二进制代码本身是没有符号的),因此可以用补码来进行减法运算。






  • 17
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值