定点数补码加减法及其溢出判断原理
补码加减运算
补码的数学表示
设X为一个数的真值,M=2n(n为机器位数),则在数学表示上
[X]补=M+X (modM),−2n−1≤X<2n−1
补码加法
[X]补+[Y]补=M+X+M+Y(modM)=M+X+Y(modM)=[X+Y]补
可见,补码加法直接使用加法器相加即可
补码减法
[X]补−[Y]补=M+X−M−Y=X−Y(modM)=M+X+M−Y(modM)=[X]补+[−Y]补
补码减法可以转化为补码加法,这也是计算机可以只设计加法器而不一定需要减法器的原因
如何将[Y]补与[−Y]补进行转化是补码减法的重点
设[Y]补=YnYn−1…Y1
(1)当0≤Y<2n−1时
[Y]补=[Y]原=0,Yn−1Yn−2…Y1[−Y]原=1,Yn−1Yn−2…Y1
Y为正,-Y为负,则
[−Y]补=1,¯¯¯¯¯¯¯¯¯¯¯Yn−1 ¯¯¯¯¯¯¯¯¯¯¯Yn−2…¯¯¯¯¯Y1+1
(2)当 −2n−1<Y<0 时
[Y]补=1,Yn−1Yn−2…Y1[Y]原=1,¯¯¯¯¯¯¯¯¯¯¯Yn−1 ¯¯¯¯¯¯¯¯¯¯¯Yn−2…¯¯¯¯¯Y1+1[−Y]原=0,¯¯¯¯¯¯¯¯¯¯¯Yn−1 ¯¯¯¯¯¯¯¯¯¯¯Yn−2…¯¯¯¯¯Y1+1
Y为负,-Y为正,则
[−Y]补=[−Y]原=0,¯¯¯¯¯¯¯¯¯¯¯Yn−1 ¯¯¯¯¯¯¯¯¯¯¯Yn−2…¯¯¯¯¯Y1+1
综上所述:机器负数转换方法为
[−Y]补=∼[Y]补+1
溢出判断
溢出产生的原因
由于机器存放数字的二级制数码位数有限,当进行模M加法时会出现异常的符号改变现象,称为溢出。溢出分为以下两种:
- 正溢:两个整数相加得到一个负数
- 负溢:两个负数相加得到一个负数
溢出检测
假设加法情况如下:
操作数A:[X]补=XnXn−1…X1操作数B:[Y]补=YnYn−1…Y1两数和:[S]补=SnSn−1…S1
方法一:直接检测
当A>0,B>0但S<0时或A<0,B<0但S>0时显然发生了溢出,表示为:
溢出=XnYn¯¯¯¯¯¯Sn+¯¯¯¯¯¯¯Xn ¯¯¯¯¯¯YnSn
方法二:进位检测
假设两数运算时产生的进位分别是CnCn−1…C1
那么根据刚才的讨论可以得到
- 当A>0,B>0但S<0时,An=0,Bn=0,Sn=1,即n-1位发生进位,n位不可能进位,Cn−1=1,Cn=0;此时正溢
- 当A<0,B<0但S>0时,An=1,Bn=1,Sn=0,即n位发生进位,n-1位不可能进位,Cn=1,Cn−1=0;此时负溢
- 当A>0,B>0但S>0时,An=0,Bn=0,Sn=0,即均不进位,Cn−1=0,Cn=0;此时不溢出
- 当A<0,B<0但S<0时,An=1,Bn=1,Sn=1,即均进位,Cn−1=1,Cn=1;此时不溢出
综上所述,那么可以得到溢出=Cn−1⊕Cn
方法三:双进位检测
在运算时临时将两操作数的符号位复制一位补在最高位+1的位置
这样运算就会变成
操作数A:[X]补=XnXnXn−1…X1操作数B:[Y]补=YnYnYn−1…Y1两数和:[S]补=Sn2Sn1Sn−1…S1
根据Sn2Sn1的不同结果,我们就可以判断是否发生溢出,这个原理与进位检测其实是相同的
Sn2Sn1=00;无溢出Sn2Sn1=01;正溢Sn2Sn1=10;负溢Sn2Sn1=11;无溢出
为了节约存储位数,最后保存结果时会忽略最高位的Sn2的计算结果,仅在运算时扩充为双符号位
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通