通过上溢出实现二进制的减法(笔记)

一.溢出

在数学的理论中,数字可以有无穷大,也可以有无穷小,但是现实中,计算机系统总会有一个
物理上的极限,因此不可能表示无穷大或者无穷小的数值.对于计算机,无论何种数据类型,
都有一个上限或者下限.

Python3中数据长度是动态的,理论上支持无限大的数
可以通过sys.getsizeof()函数来查看某个数值占用多少字节.

一旦某个数值超出了限定值,就会溢出:如果超出上限,就叫上溢出(overflow);如果超出下限,
就叫下溢出(underflow).

例:上溢出
n位数字的最大的正值,其符号位为0,剩下的n-1位都为1,再增大一个就变为符号位为1,剩下的
n-1位都为0,即-2n-1.也就是说,上溢出之后,又从下限开始,最大的数值加1,就变成了最小的
数值,周而复始,这就是余数和取模的概念.

计算机的溢出就相当于取模.而用于取模的除数就是数据类型的上限减去下限的值,再加上1,
也就是(2n-1-1)-(-2n-1+1)=2*2n-1-1+1=2n-1+1
2n-1+1.

这个除数不能直接写成2n,因为2n已经是n+1位了,已经超出了n位所能表示的范围.

二.二进制的减法实现

是否可以直接用负数的原码来进行减法运算呢?
例:3-2
可以看做3+(-2)

3的原码是0011
-2的原码是1010
0011+1010=1101
结果为-5,显然不符合3-2的差.

对计算机的减法进行变换,假设有i-j,其中j为正数,如果i-j加上取模的除数,就会产生溢出,并
正好能够获得我们想要的i-j的运算结果.
表达式:
i-j=(i-j)+(2n-1+1)=i+(2n-1-j+1)=i+(2n-1-j)+1

2n-1-j,其中2n-1在不考虑符号位的情况下就是n-1位的1
假设j=-2:
1111-0010=1101
从结果可以观察出来,所谓2n-1-j相当于对正数j的二进制原码,除符号位之外按位取反(0变
1,1变0),因为负数-j和正数j的原码,除符号位之外都是相同的,所以2n-1-j也相当于对负数-j的
二进制原码,除符号位之外按位取反.所以说2n-1-j对应的编码称为负数-j的反码

有了反码的定义,我们可以得出新的表达式:
i-j=i的原码+(-j的反码)+1

引入补码的定义:将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1
即反码后+1

由此得出新的表达式:
i-j=i的原码+(-j的补码)

例:3-2
可以看做3+(-2)
3的原码是0011
-2的补码是1110
0011+1110=0001
结果为1,符合3-2的差

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值