补码乘法

补码乘法

(写的很乱,很杂,反正也没有人看 :>,就不讲究了)

起因

昨天嵌入式系统课上,老师专门讲了,补码的一系列运算.可是我没有听懂补码乘法相关的内容(补偿法?),所以自己再推一下.

前提

  1. 在不溢出的前提下,补码所表示的数可以进行正确的左移运算,并且,左移等价于乘2
  2. 补码的加法可以通过溢出保证结果的正确性,(无论对于有符号数还是无符号数)
  3. 由(1)(2)知当第二个乘数为正时,无论第一个乘数的正负号,都可以保证结果的正确性(不溢出的情况下),因为运算相当于左移和加的结合.

当第二个乘数为负数时

这里以8位二进制数乘8位二进制数,并且用16个二进制位来保存结果为例.
使用AAA,BBB分别表示第一个和第二个乘数的绝对值,数值直接写作补码的形式,或称为unsigned 的形式(当作unsigned 时计算也是正确的).

  • 如果我们只是直接按照unsigned 进行乘.
    A×(28−B)=扩展成16位A×(216−B)=A×(216−B)mod  216=A×216mod  216−A×Bmod  216=0−A×Bmod  216=216−A×BA \times (2^8-B)\xlongequal{\text{扩展成16位}}A\times (2^{16}-B)\\ =A\times (2^{16}-B)\mod 2^{16}\\ =A\times 2^{16}\mod 2^{16}-A\times B\mod 2^{16}\\ =0-A\times B \mod 2^{16}\\ =2^{16}-A\times BA×(28B)扩展成16A×(216B)=A×(216B)mod216=A×216mod216A×Bmod216=0A×Bmod216=216A×B
    那么我们会得到正确的结果,但是显然前面补充的符号位是没有必要的.
  • 我们以可以对AAA,BBB进行求补,即 A×(28−B)=(28−A)×BA\times (2^8-B)=(2^8-A)\times BA×(28B)=(28A)×B
  • 补码校正法,只应用了一次取补,结论是:
    [A×B]补=A补×(0bn−2bn−3⋯b2b1b0)+[−A]补×2n−1×bn−1[A\times B]_补=A_补\times (0b_{n-2}b_{n-3}\cdots b_2b_1b_0)+[-A]_补\times 2^{n-1}\times b_{n-1}[A×B]=A×(0bn2bn3b2b1b0)+[A]×2n1×bn1
    推导:
    A×(28−B)=discard msb扩展到16位(A×(27−B)+C(补偿))mod  216=(A×27−AB+C)mod  216A \times (2^8-B)\xlongequal[discard\ msb]{扩展到16位}(A\times (2^{7}-B)+C(补偿))\mod 2^{16}\\ =(A\times 2^7-AB+C)\mod 2^{16}A×(28B)扩展到16discard msb(A×(27B)+C(补偿))mod216=(A×27AB+C)mod216
    mod  216\mod 2^{16}mod216的意义下,取C=216−A×27C=2^{16}-A\times 2^7C=216A×27即是−A-AA的16位补码.

总结

在乘的时候只要保证unsigned的值合法,负数的值就是合法的,原理是同余定理,无论是unsigned还是负数在mod  216\mod 2^{16}mod216的意义下都是相同的.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值