关于补码的一些思考

一、补码的优点

1、可以将减法转化为加法,在计算机中只保留加法

2、将符号位参与运算

二、如何实现?

我们先以钟表为例子,假设现在的标准时间为4点整,而有一个钟的时间为7点整。我们可以将时针逆时针旋转3格,或者将时针顺时针旋转9格,如图。

7-3=7+9=4  mod(12)

上述式子为一个同余式,同余式的标准定义为

a ≡b (mod n) 

即同余式两边的数值,对n进行取余后的数值相等。

从上述例子我们可以得到灵感,即用一个正数来替代负数(上述例子中用9替代-3)从而将减法转化为加法。

在计算机中,我们应该如何进行这种替换?

我们应先明确一些概念,如原码表示,加法器的溢出,负数取余。

原码表示:最高位为符号位

正数:符号位为0,剩余的为数值

如用8位表示一个数,则+8为 0000 1000(2)

负数:符号位为1,剩余的为数值

如用8位表示一个数,则-8为 1000 1000(2)

采用原码来进行计算机的运算,将会非常复杂,因为将会有很多逻辑判断。

如两数相加时,同好则数值相加;不同号则相减,而且还要比较数值部分的绝对值的大小。

所以人们找到了补码的表示方法。

加法器的溢出:

假如一个加法器为8位的加法器,当和的值超过了 1111 1111(2),那么高位将被丢弃。

如 1111 1111(2)+ 1111 1111(2)= 1111 1110(2)

也就是说这个加法器只能表示0-255,即256为一个轮回,从我们的角度来看的话,这个加法器对结果进行取余,其为256。

让我们推广到一般情况,n位加法器

xnxn-1……x0,即只能表示0-2n+1-1,即2n+1为一个轮回,从我们的角度来看的话,这个加法器对结果进行取余,其为2n+1

负数的取模:

 我们应该先探讨一下负数的取模操作,我们知道取模公式如下所示:

x mod y = x - y* [x/y]

注:[x/y]为下取整符号

上边我们说到要用正数来取代负数从而达到,将减法转化为加法,那么应该怎么取代,关系式是怎么样的?

 对于一般二进制数xnxn-1……x0进行探讨,从上边的讨论我们知道,对这个二进制数进行加减操作时,最终的结果都将进行模为2n+1的取余操作。我们假设这个二进制数值为[x]其代表的真值为x

1、当xn为0时,[x]=x,范围为0 - 2n-1

2、当xn为1时,其代表的为负数x,我们知道这里应该用一个正数[x]来取代负数x,并且使模为2n+1的同余式相等。

让我们先来讨论-1,-1对2n+1进行取余,即

-1 mod 2n+1 = -1 - 2n+1*(-1) = 2n+1 - 1

[2n+1 - 1]补 = -1

所以我们用2n+1 - 1替代-1

则对负数x为,

x mod 2n+1 = x - 2n+1*(-1) = 2n+1 + x

[2n+1 + x]补 = x

x的范围为-1至-2n

所以我们用2n+1 - 1替代x

至此我们就可以得出补码的公式了:

我们还要进行证明,用补码进行加法时是否正确。

即我们需要证明,

[x]补 + [y]补 = [x+y]补   (mod 2n+1

这里有四种情况

1、x>0, y>0

[x]补 + [y]补 = x + y = [x+y]补   (mod 2n+1

2、x>0, y<0

[x]补 + [y]补 = x + 2n+1 + y = 2n+1 + x  + y = [x+y]补   (mod 2n+1

3、x<0, y>0

[x]补 + [y]补 = 2n+1 + x + y = 2n+1 + x  + y = [x+y]补   (mod 2n+1

4、x<0, y<0

[x]补 + [y]补 = 2n+1 + x + 2n+1 + y = 2n+1 + 2n+1 + x  + y = [x+y]补   (mod 2n+1

综上,得证,补码可以将减法转换为加法,并将符号位参与运算。

注:从补码的公式可以看出还是需要做一次减法运算,所以这里用反码做过渡,先将原码变为反码,再将反码加1就得到了补码。

原文地址:https://www.cnblogs.com/songdechiu/p/5397070.html