「Section 3」补码加减运算方法

目前计算机中的数据普遍是用补码存储的,因为补码具有简单的加减法规则,运算简单,易于实现,而且符号位可以和数值位一起参与运算

α. 补码规则运算

β. 溢出检测

γ. 机器数的移位运算


α 补码运算规则

补码的加减法运算公式为

「Section 1」数据格式中我们有提过补码的减法是用加法来实现的,这里其实就是被减数的补码+减数相反数的补码,而一个正数相反数的补码显然为其各位(包括符号位)取反+1。

那么上述的公式又如何被证明呢?这里需要用数论中模(mod)的概念。我们知道正数的补码即为原码,而负数的补码则是各位取反+1,这两种情况是分开的,那是否有一种方式能将两者大一统呢?事实上,我们可以认为一个数的补码(算上符号位是 位的补码)是该数模 的结果: 这里的mod是取余的意思。我们规定余数必须为正,那么一个负数 的余数即为 ,就会发现补码的定义确实如此。

那么,

根据上式,第二个等式由 则显然成立。


β 溢出检测

我们很高兴地发现了补码运算的简便,但算着算着就会发现一些神奇的情况,比如说 怎么说呢,就是两个负数加起来变正了。想必,这就是物极必反吧(bushi

这个式子的真面目应该是 然而机器数的位数是有限制的,计算机难以容忍多出的一位,因此直接将最高位扔掉了,只是他不知道最高位有着特殊含义。这种现象我们称之为溢出(一般指上溢出)。

溢出在所难免,因此计算机必须解决溢出的问题,需要检测并指示。

❄︎ 单符号位判溢方法

我们清楚事实上只有当绝对值变大,即同号相加、异号相减(两者本质相同)的情况才会发生溢出,我们设 溢出符号位 为两个运算数的最高符号位, 为运算结果符号位,而 则表示运算符,0为+,1为-,那么有

❄︎ 进位判溢方法

为两数符号位相加的进位信号, 则是两数最高有效位的进位信号。由于补码可以将减法转换为加法,而且只有同号相加时会发生溢出,因此这里只考虑同号加法。符号位 在不受到 影响之前为0,那么考虑 后有 。而 的值则代表了两数的符号,0正1负。我们清楚运算结果的符号位若与两数符号位不同则表明溢出,即 不同。由于异号相加(不会发生溢出)时也有 ,因此可以将 的表达式直接写为

❄︎ 双符号位判溢方法

运算数采用双符号位补码(变形补码)进行运算,正数的符号位变为00,负数的符号位变为11,其余位不变。当运算结果的符号位的两位不同时表明发生溢出 。 其实这是一种对进位判溢方法的应用,设两个运算数 的符号位分别为 ,运算结果的符号位为 ,那么有
不同时 也不同。而同号运算时显然 ,那么 时说明两正数相加结果为负,为正溢出; 时说明两负数相加结果为正,为负溢出。

⚠️第一位是正确的符号位,第二位是保留溢出位。


γ 机器数的移位运算

  1. 逻辑移位:直接左右补0。将移位的数据视为无符号数据,各数据位在位置上发生了变化,导致无符号数据的数值(无正负)放大或缩小。(x86:SHL,SHR;RISC-V:sll,srl)
  2. 算术移位:将移位的数据视为带符号机器数。算术移位的结果,在数值的绝对值上进行放大或缩小,同时,符号位必须要保持不变。(x86:SAL,SAR;RISC-V:sll,sra)
    • 补码的算数右移:高位补符号位
    • 补码的算术左移:数据最高有效位必须与符号位相同才能保证不会溢出,此时可以直接将最高有效位移入符号位并在左边补0
  3. 循环移位:所有的数据位在自身范围内进行左移或者右移,左移时最高位移入最低位,右移时最低位移入最高位。(x86:ROL,ROR,RCL,RCR)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值