补码运算溢出有两种溢出, 一种是正数和正数相加得到负数, 一种是表示数字的位数不足引发的溢出
为什么会溢出, 因为满了
一颗四位的运算器, 取值范围为[0000, 1111]
补码区间是[-8, 7]
, 定义两个变量a
和b
, 变量的范围是这个区间
正数溢出情况
- 首先输入一个数
7
给a
- 再输入另个数
1
给b
- 让
a
和b
相加 - 结果很简单是
8
- 但是4位二进制补码能表示的最大正数为
7
- 来看看补码是怎么操作的:
a = 0111
b = 0001
a + b = 1000 // -8
b = 0010 // 如果b = 0010
a + b = 1001 // 7 + 2 = -7
负数溢出情况
a = 1111 // -1
b = 1000 // -8
a + b = 1 0111 // 舍去溢出位, 0111是 7
// -1 - 8 = -9 ≠ 7
溢出的情况之所以会出现, 是因为你缺乏"释放"
显然, 仅仅是4位二进制数满足不了我们的运算要求, 如果是5位, 甚至是8位
就能正确运算出结果
以五位为例
// 7 + 1
0 0111 + 0 0001 = 0 1000 // 8
// 最高位为符号位, 次高位就不是了
// -8 - 1
1 1000 + 1 1111 = 1 0111 // -9
“压抑”, 对溢出做一定的管理
因为我们的区间只有[-8, 7]
, 只要想办法让运算结果不超出这个范围就ok了
思路是: 如果给的太多了, 要溢出了, 我们就不要了
设a
为 5
, b
为 6
, 让a
加 b
显然会超出我们的区间
负数加负数, 正数加正数会发生溢出, 正数加负数永远不会溢出
减法呢?
除了a
和 b
的值, 我们还知道, 正数取值的极限是7
7
减去 a
我们得到 2
, 这个2
就代表了a
能加的最大的数, 超过这个数它就要溢出了
显然b > 2
也就是说a
承受不了 b
, b
会让a
溢出
所以, 我们就不进行这次加法运算
结论: 简单的溢出逻辑判断(加法)
二进制运算中只有加法, 如果是在程序中就要考虑减法