补码怎么在计算机内的加减法运算中发挥作用(定点数)?

本文详细阐述了计算机内部原码与真值的区别,重点讲解了定点数的补码存储方式,以及加法和减法运算原理,包括溢出判断方法,如双符号位和单符号位检测。还介绍了行波进位加减法器的电路设计,以及补码的一些特性。
摘要由CSDN通过智能技术生成

目录

1. 原码与真值

2. 计算机内部定点数的存储

3. 加法运算

4. 减法运算

5. 运算溢出判断

5.1 双符号位溢出检测法

5.2 单符号位溢出检验法

6. 行波进位加减法器

7. 补充


1. 原码与真值


我们人类所习惯使用的数据都是以真值的形式存储的,如+3,-0.8125等,均是符号位加上数值部分(一般为十进制形式)构成,然而这将不利于在计算机内部的存储和使用。离数据在计算机内部存储形式更接近的,是原码形式,将真值中的 '+' 号以0代替,置于最高位当作符号位,将真值中的 '-' 号以1代替,置于最高位当作符号位,数值部分则使用二进制,如 +3 的原码为 0011,-0.8125的原码为1.1101.

2. 计算机内部定点数的存储


真实地,计算机内所有的定点数(包括定点小数、定点整数)都是以补码(也称2的补码)的形式存储的。可以认为只有负数才有补码的形式,这是因为:

对于正数而言,其补码与其原码完全相同;

而对于负数而言,其补码则为 模值 - 负数的绝对值,所谓模值,对于n位定点整数而言(包括符号位),其模值为2^n,例如 1010 的模值就是 1 0000。对于定点小数而言,其模值为2,如 1.1101 的模值为 10.0000。回到负数的补码,如:

要计算原码 1101 的补码,则为:

  

上图中 1 0000 即为 -5 的模值,而所得的 1011 即为 -5 的补码(对于n为数,我们只关心n位结果,超过的部分忽略),

再如,要计算 1.0101 的补码,则为:

上图中 10. 0000 即为 1.0101 的模值,而所得的 1.1011 即为 1.0101 的补码.

需特别注意几个特殊数的补码形式:

· [X]补 = 1000 0000, X = -128

· [X]补 = 0000 0000, X = -0 / 0(正负 0 的补码均相同,这就是补码的魅力之一)

· [X]补 = 1.0000,       X = -1.0000(表示 -1,而非 -0.0000)

· [X]补 = 0.0000,       X = -0.0000 / 0.0000

这里介绍求取负数补码的快速方法(以 -0.0101为例):

        step1:写出待求负数的绝对值的原码形式(0.0101);

       step2:对上述所得,从右往左第一个 1 及其右边的 0 保持不变,其余位按位取反(1.1011),所得的数即为补码;

       注:若没有 1 ,则所有数保持不变,如 -0.0000,其绝对值原码形式为0.0000,遵循上述步骤得其补码为 0.0000,体现了负0的补码仍为 0.0000.

3. 加法运算


无论正数、负数,在计算机内都是以补码形式存储的,在运算时以补码运算,所得结果也为补码形式。使用补码运算时,在不发生溢出的情况下,所得结果忽略进位后是正确的。加法运算较为简单,只需将两个加数的补码相加,进位忽略即可,所得结果为 和值的补码形式:

见以下三个例题:

4. 减法运算


两个数做减法,应转化为 被减数 加上 减数的相反数,根据上述提及的补码加法原理,减法结果的补码形式 为 被减数的补码 加上 减数的相反数的补码,即 

被减数的补码形式求解利用上述方法很容易可以求得,而对于减数相反数的补码 请读者参看以下性质:

一个数相反数的补码,是该数补码全部取反后末尾加1,即:

 

这里给出一个样例,欲求 -0010 的相反数的补码,先求出 -0010 的补码,即 1110,再对该补码全部取反得 0001,最后末位加1得 0010,即为所求.

这样,我们就可以进行减法运算了,参看以下三道例题:

5. 运算溢出判断


上述运算过程中提到出现进位可以直接忽略,取有效位数范围内结果即可,这建立在运算结果不超过补码所能表示的范围的前提之下:

对于 n 位(含符号位)补码定点小数,其表示的范围为-1 \sim1 - 2^{-(n-1)};对于 n 位(含符号位)补码定点整数,其表示范围为-2^{n-1} \sim 2^{n-1} - 1;可见,特定位数的补码进行运算时,若运算结果超过所能表示的数值范围,就会发生溢出,导致错误的结果.

定义两个名词:

在定点计算机中,从正方向超过了数的表示范围,称为上溢;

在定点计算机中,从负方向超过了数的表示范围,称为下溢;

例如,对于存在 3 位有效位,1 位符号位的两个加数 0111(+7)、0010(+2),其加法运算结果为 +9,显然超过最大数值所能表示的范围,因此直接使用补码运算所得结果为 1001,是错误的,这是十分危险的情况,因此有必要通过特殊的信号来判断是否存在运算溢出的现象。实现这一目的的手段有很多,这里仅介绍两种常用方法.

5.1 双符号位溢出检测法

双符号位溢出检测法,此处以-0.1100、-0.1000的加法为例,其步骤是:

step1:写出数的补码形式,1.0100、1.1000;

step2:将数的符号位拷贝一次放到原符号位之前,此时有两个重复的符号位,11.0100、11.1000;

step3:两数相加得到双符号位下的和的补码:

           

step4:对双符号位进行判断,结果为发生下溢出.

双符号位                   含义        
00结果为正数,无溢出
11结果为负数,无溢出
01发生上溢,即结果超过范围上限
10发生下溢,即结果超过范围下限

下面再看一个例子:求 (-7) + (-2)的结果:

-7的补码形式为1001 ,-2的补码形式为1110 ,扩充为双符号位分别为 11001 、11110,求和有:

显然发生了下溢出。因此可以对 原符号位 与 扩充符号位的运算结果C{n}, C{n-1}进行异或运算, Overflow = C_{n}\oplus C_{n-1},由 Overflow 信号可判断是否发生溢出.

5.2 单符号位溢出检验法

这里仅给出判断方法,对于数值最高位产生的进位C_{n-1}、符号位产生的进位C_{n},若二者不同,则说明发生溢出,给出以下两个示例:

示例一
示例二

显然示例一发生了溢出现象,而示例二未发生.

6. 行波进位加减法器


由以上论述,在计算机内部,欲求 两数(补码形式存储)之 (补码形式存储),只需对两数补码直接相加即可,而欲求两数(补码形式存储)之 (补码形式存储),需要用被减数的补码 加上 减数相反数的补码。因此可以设计以下加减法器电路:

🚩上图中,FA 表示 一位全加器,其作用可简单描述为:将来自低位的进位 Cin 与 两个加数 A、 B 相加,所得一位和值输出为 S,所产生的进位输出为 Cout.

🚩M 表示操作符,当执行加法运算时,M为0,由于0与任何数做异或都不改变其值,故加数、被加数都以原来的补码数值进入 FA 中参与计算。当执行减法时,M为1,由于 1 与任何数进行异或运算都会对该数取反,故所有的加数      B_{n-1}, B_{n-2} ... B_{1},B_{0} 均被取反,由于 M 连接至第一级全加器的低位进位端,恰好能满足求一个数相反数的补码全位取反,末位加1的要求,从而实现减法运算.

🚩根据 5.2 运算溢出判断 - 单符号位溢出检验法 中的描述,对最后两级加法器的进位进行异或判断,可检测是否发生溢出现象.

7. 补充

1. 互为相反数的两个数的补码之和为0:

2. 原码下0有正0、负0之分:

而补码下的0均为 0.0000形式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值