原码和补码在计算机中的应用,二进制、原码、反码和补码详解

原码反码和补码都是计算机中表示数字的一种编码,维基百科上说

编码是信息从一种形式或格式转换为另一种形式的过程。

其实,计算机内部使用二进制,n位的二进制一共可以表示2^n个不同的数字,至于具体哪个二进制序列对应哪个数字,原则上可以随意。

例如,我们可以编码 00代表数字2  01代表数字3 10代表7 11代表9 ……

c2a138391a7c63120d37616d4e16575a.gif

但是实际应用时,必须考虑到这种编码可以给应用带来方便。相信没有人会设计上图中的编码 ==因为这种编码需要制定每一个数字的编码,而且面对编码根本不知道表示的是哪个数字,只有查表……

从这个扯淡的例子中,我们看到编码必须有一定的规律性,最好能够直接从编码计算得到表示的数字。

二进制数字

计算机采用二进制,而一个数字也可以写成二进制形式,这种一一对应关系恰好可以用于编码。

我们先看一下关于进制的知识:

我们平时使用的数字是十进制,它的全称是10进位计数制,它以10为基数,有0到9 十个符号,进位规律是“逢十进一”,它在表示一个数时,不同的位上的数字的含义是不同的。例如,个位上的3表示3  而十位上的3就表示3*10 。

c2a138391a7c63120d37616d4e16575a.gif

与十进制类似,以2为基数(有两个符号0 1)的进位计数制称为二进制。

我们以二进制数字1011001.1011为例,二进制数字上的每一位的位权如下图所示

c2a138391a7c63120d37616d4e16575a.gif

1011001.1011的十进制形式 为 64 + 16 + 8 + 1 + 1/2 + 1/8 + 1/16 = 89.6875

原码

使用数字的二进制形式在计算机中表示数字,对于一个正数,例如6 ,(6=4+2+0)我们可以很快写出它的二进制形式110 。但是对于负数-6,二进制形式为-110,但是计算机并不认识负数(-)。一个很自然的想法是,用一位二进制0或1分别表示正数和负数(其实也可以用其他方式,只要区分就可以,但这种方式是最方便自然的)。我们把这一个标示符号的为叫做符号位,而数字6的表示部分叫做数值位。

加上符号位之后,6就可以在计算机内表示为0110 ,而 -6可以表示为1110 。(这是用4位表示的情况)

这就是原码,由符号位加上数字绝对值的二进制形式作为数值位表示。

原码对人来说阅读起来十分方便,但是对计算机来说,却有着不少缺点。

原码表示法中,0有两种不同的表示方法0和-0: 以8位表示1个数字为例 0000 0000 和1000 0000都表示0 。这对于计算机来说很不友好,如果判断一个数是不是0要做两次判断。

求两个数的和的时候,如果符号不一致,那么不能直接相加。例如3 + (-4)  用4为2进制表示 就是0011 + 1100 ,如果直接相加 等于1111 这个结果和3+(-4)的正确结果没什么关系。由此可见,符号不相同的时候必须先判断一下两个数的绝对值,绝对值较大的减去较小的,符号是跟绝对值较大的数相同。这样进行加法运算是十分复杂的。

反码

由于用原码计算的时候要单独考虑符号位,比较麻烦,于是人们开始探索将符号位一起进行运算的方法。

反码的定义:正数的反码就是他的原码,负数的反码是他的原码的数值位取反~符号位仍为1.

使用反码表示后,符号位可以一起参与运算,不过有着一些缺点

加法产生进位的时候,要在最低位加上1

0仍有两种表示方式 0000 0000 和 1111 1111

由于这些缺点,反码的应用大大不如补码。

补码

使用原码的时候,正数加负数,实际却要进行减法,而负数减负数,实际却要进行加法,这是十分复杂的。引入补码的目的是方便的实现运算器对于有符号数的加减法运算。

补码是建立在“模”的概念的基础上的。模可以理解为一个量程,一个范围,当运算超出模的范围的时候会循环到最开始。

c2a138391a7c63120d37616d4e16575a.gif

以钟表为例,要把时针从2点移动到4点,既可以顺时针转2小时,也可以逆时针转10小时。

为什么逆时针转10小时也能达到这种效果呢,这就是这种循环特性造成的。

由此我们可以说,对于模12来说

4 = 2 + 2 (mod 12)

4 = 2 +(-10) (mod 12)

也就是说模12的情况下对2进行+2 和 -10 效果是一样的。我们说2和-10对模12互补。

同理,在这个钟表上,-1和+11是一样的,-5和+7的结果是一样的。

所以计算的时候 -6 可以看做+6    -3可以看做+9

再想一下,在这个表上,一个数如果减去一个小余模12的数,相当于加上(12-这个数)

因此,可以把减法转换为加法。

补码和数字之间的映射关系

以3位为例

c2a138391a7c63120d37616d4e16575a.gif

c2a138391a7c63120d37616d4e16575a.gif

3位的二进制可以表示8个数字,其中分为两部分,负数和非负数。0和正数的补码就是它们的原码,而负数的补码就要是它们的绝对值相对于2^4的补码。

-1的绝对值 1 它的补码 就是相对于1 000 来说的补码 1000 – 1 = 111

-2的绝对值 10 它的补码 1000 – 10 = 110

-3的绝对值 11 补码 1000 – 11 = 101

-4的绝对值 100 补码 1000-100=100

用多少个位表示补码,它的模就是1后面有多少个0 。例如用8位表示,它的模就是1 0000 0000 = 2^8

用这个表示的时候 如果计算3-2 ,可以计算3 + (-2)

用他们的补码计算  011 + 110 = 1001 由于只有3位 第4位舍去,结果正好是001 也就是1

补码的计算

补码只是一种相对合理的编码方案,对于人来说可以用补码的形式求出,但是对于计算机来说却不好操作。所以人们又研究出了许多种求补码的方法。

利用定义,也就是负数的补码 = 2^n+1 + x

利用补码=反码+1

扫描方法

将负数的原码或真值转换为补码,可以从最低位开始,到最高位依次扫描,如果没有遇到1 就保持不变(开始的0仍是0) 遇到第一个1后,1后面的各个位数依次取反。最后将最高位符号位置为1.这种方法对人和机器都非常方便。

移码

移码就是将x加上一个常数,相当于在数轴上向右平移了一段距离。

常用的移码距离是2^n 。

c2a138391a7c63120d37616d4e16575a.gif

移码可以这样理解,本来-128 到 127 256个数字都是用-128和127表示,但是经过移码后,-128到127依次映射为0-255

对于补码,它的移码就是最高位翻转,这样0表示负数 1表示正数,利于判断大小,被用在浮点表示中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值