“补码”的数学原理

来源:互联网 发布:chart.js 更新数据 编辑:程序博客网 时间:2024/05/16 15:08

摘要:本文介绍补码进行运算为什么是有效的。
通过求同“同余”将减法变成加法;而求补码就是求同余。

1. 原码、反码和补码

1.1 原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.
>

[+1]原 = 0000 0001
[- 1]原 = 1000 0001

1.2 反码

正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

1.3 补码

正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

2. 同余

定义1:两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余。

例如,当m=12时,3跟15是同余的,因为3mod12=3=15mod12

对于同余,有如下结论:

  1. a,b是关于m同余的,当且仅当,二者相差m的整数倍,
    ab=k×m,withk=2,1,0,1,2,
    即,
    a=b+k×m,withk=2,1,0,1,2,
  2. 一个数x加a对m取余,等于x加a的同余b对m取余,即,
    (x+a)modm=(x+b)modm.
    由1.易知2.是成立的。

3. 为什么补码是有效的

3.1 将减法变成加法

我们知道计算机只有加法器,没有减法器,那么就需要将加法变成加法。怎么变?
经过上面的介绍,我们知道,在对m取余的情况下,加上一个数,相当于加上这个数的同余,即,
若,b=a+m,则 (x+a)modm=(x+b)modm.

举个例子:
以时钟的时针为例,因为,10 = -2 + 12。
当前时刻t=3,向后拨2个小时得,(t2)mod12=1mod12=1
也就相当于向前拨10个小时,(t+10)mod12=13mod12=1
结论:通过同余,减法操作变成了加法操作

3.1 求同余就是求补码

我们通过证明:负数的补码和原码之和等于m,来证明求同余的过程就是求补码。

定义2:
定义m为除去符号位后,能表示的数字的个数。
例如,用8位表示整数,除去符号位,还剩7位,能表示的数字的就是000 0000~111 1111,共128个数字。所以此时m=128.

负数的补码等于原码的符号位不变,其它位取反,再加1
那么不看不符号位,将负数的补码和原码相加等于多少呢?
全1再加1,就等于m!

例如,用8位表示整数-3,原码为1000 0011,补码为,1111 1101,不看符号位,将二者相加得,1000 0000 = 128.

3.2 用同余进行计算

后面我都将以用8位表示的整数运算,32为例进行分析。

  1. 由于8位除去符号位后的m等于128,那么1282=126,即126=2+128,根据上面的分析:

    (32)mod128=(3+126)mod128

    题外话:为什么要模128,因为我们只关注后7位,如果和大于等于128,将进位。

    这样,减法就变成了加法,也可以看成,将所有含负数的运算变成了只含正数的运算。工作还没有完。

  2. 我们进行上述计算:

    • 3的编码为:0000 0011(由于是正数,原码反码补码相同)
    • 126的编码:0111 1110
    • 二者相加得,1000 0001

    结果错误,这是负1的编码。

  3. 我们发现上述运算的结果正好差一个负号,怎么办?这时候就轮到符号位出场了,刚才我们说的运算都忽略了符号位,现在把它加上:

    • 3的编码:0000 0011
    • 126的编码:1111 1110(因为126对应的是-2,因此其符号位为1)
    • 二者相加得:1 0000 0001,因为我们只看8位,得 0000 0001.

    结果正确!这就叫符号位参与运算

  4. 以上过程就是补码参与运算的过程。

4. 总结

计算机只能用有限的位表示整数本来是个劣势,而正是这个劣势让减法变成加法成为可能。塞翁失马焉知非福。
以上。

0 0
原创粉丝点击