定点数加减法及其溢出判断原理

定点数补码加减法及其溢出判断原理

补码加减运算

补码的数学表示

设X为一个数的真值,M=2n(n为机器位数),则在数学表示上
[X]=M+X (modM),2n1X<2n1

补码加法

[X]+[Y]=M+X+M+Y(modM)=M+X+Y(modM)=[X+Y]
可见,补码加法直接使用加法器相加即可

补码减法

[X][Y]=M+XMY=XY(modM)=M+X+MY(modM)=[X]+[Y]
补码减法可以转化为补码加法,这也是计算机可以只设计加法器而不一定需要减法器的原因
如何将[Y][Y]进行转化是补码减法的重点
[Y]=YnYn1Y1
(1)当0Y<2n1

[Y]=[Y]=0,Yn1Yn2Y1[Y]=1,Yn1Yn2Y1

Y为正,-Y为负,则

[Y]=1,Yn1¯ Yn2¯Y1¯+1

(2)当 2n1<Y<0

[Y]=1,Yn1Yn2Y1[Y]=1,Yn1¯ Yn2¯Y1¯+1[Y]=0,Yn1¯ Yn2¯Y1¯+1

Y为负,-Y为正,则

[Y]=[Y]=0,Yn1¯ Yn2¯Y1¯+1

综上所述:机器负数转换方法为
[Y]=∼[Y]+1

溢出判断

溢出产生的原因

由于机器存放数字的二级制数码位数有限,当进行模M加法时会出现异常的符号改变现象,称为溢出。溢出分为以下两种:

  1. 正溢:两个整数相加得到一个负数
  2. 负溢:两个负数相加得到一个负数

溢出检测

假设加法情况如下:

A:[X]=XnXn1X1B:[Y]=YnYn1Y1[S]=SnSn1S1

方法一:直接检测

当A>0,B>0但S<0时或A<0,B<0但S>0时显然发生了溢出,表示为:

=XnYnSn¯+Xn¯ Yn¯Sn

方法二:进位检测

假设两数运算时产生的进位分别是CnCn1C1
那么根据刚才的讨论可以得到

  1. 当A>0,B>0但S<0时,An=0,Bn=0,Sn=1,即n-1位发生进位,n位不可能进位,Cn1=1Cn=0;此时正溢
  2. 当A<0,B<0但S>0时,An=1,Bn=1,Sn=0,即n位发生进位,n-1位不可能进位,Cn=1Cn1=0;此时负溢
  3. 当A>0,B>0但S>0时,An=0,Bn=0,Sn=0,即均不进位,Cn1=0Cn=0;此时不溢出
  4. 当A<0,B<0但S<0时,An=1,Bn=1,Sn=1,即均进位,Cn1=1Cn=1;此时不溢出

综上所述,那么可以得到=Cn1Cn

方法三:双进位检测

在运算时临时将两操作数的符号位复制一位补在最高位+1的位置
这样运算就会变成

A:[X]=XnXnXn1X1B:[Y]=YnYnYn1Y1[S]=Sn2Sn1Sn1S1

根据Sn2Sn1的不同结果,我们就可以判断是否发生溢出,这个原理与进位检测其实是相同的

Sn2Sn1=00;Sn2Sn1=01;Sn2Sn1=10;Sn2Sn1=11;

为了节约存储位数,最后保存结果时会忽略最高位的Sn2的计算结果,仅在运算时扩充为双符号位

posted @   Artlesbol  阅读(1046)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示