例 1:X=−0.1010, Y=−0.1011X=-0.1010,\ Y=-0.1011#

先写补码。被乘数写双符号位的 [X]补[X]_{\text{补}} 和 [−X]补[-X]_{\text{补}},乘数写单符号位:

[X]补=11.0110[−X]补=00.1010[Y]补=1.0101\begin{aligned} [X]_{\text{补}}&=11.0110\\ [-X]_{\text{补}}&=00.1010\\ [Y]_{\text{补}}&=1.0101 \end{aligned}

算系数#

第一步永远是 YY 结尾无脑补一个 0,变成 1.01010。

然后从左向右,依次用右边一位减去左边一位,如下过程:

text
0-1=-1
1-0=1
0-1=-1
1-0=1
0-1=-1
text
乘数: 1 . 0  1  0  1  0
系数:-1 . 1 -1  1 -1

列竖式#

和小学竖式一样,列乘法竖式。从系数低位开始,从右向左乘过去:−1-1 就写 [−X]补[-X]_{\text{补}},11 就写 [X]补[X]_{\text{补}},每往下一行向左错开一位。

每一行首位数是 1 就往左补齐 1,是 0 就补齐 0。比如 [X]补[X]_{\text{补}} 110110 补齐成 111110110。

text
          0000001010
          111110110
          00001010
          1110110
        + 001010
          ----------
          0001101110

然后相加,留头两位作为符号,得到 00.01101110:

[X⋅Y]补=0.01101110\boxed{[X\cdot Y]_{\text{补}}=0.01101110}

例 2:X=−0.1101, Y=+0.1011X=-0.1101,\ Y=+0.1011#

[X]补=11.0011[−X]补=00.1101[Y]补=0.1011\begin{aligned} [X]_{\text{补}}&=11.0011\\ [-X]_{\text{补}}&=00.1101\\ [Y]_{\text{补}}&=0.1011 \end{aligned}

算系数#

YY 结尾补 0,变成 0.10110。从左向右,右边一位减去左边一位:

text
1-0=1
0-1=-1
1-0=1
1-1=0
0-1=-1
text
乘数: 0 . 1  0  1  1  0
系数: 1 .-1  1  0 -1

列竖式#

还是系数从右到左依次乘过去。遇到系数 00 那一行直接写一排 0;或者干脆不写下一行直接多错一位就行:

text
          0000001101
          11110011
          0001101
        + 110011
          ----------
          1101110001

相加,留头两位作为符号,得到 11.01110001:

[X⋅Y]补=1.01110001\boxed{[X\cdot Y]_{\text{补}}=1.01110001}

符号位是 01 怎么办#

01 就是正溢出:结果超出了定点小数能表示的范围。

单符号位的补码小数只能表示 −1≤x<1-1\le x<1:最小是 1.0000,即 −1-1;最大是 0.1111,即 1−2−41-2^{-4}。+1+1 写不出来。

两个数都在这个范围里,乘积的绝对值不会超过 11。只有 X=Y=−1X=Y=-1 时乘积正好等于 +1+1,这时溢出。

10 不会出现:10 要求乘积小于 −1-1,必须有一个数是 +1+1,不过 +1+1 表述不出来。

顺便:原码一位乘#

原码就是符号位加绝对值,比如 −0.1101-0.1101 的原码是 1.1101。

原码乘法更简单,就是小学竖式:符号位异或,数值部分直接乘,不用补符号位。

例:X=−0.1101, Y=+0.1011X=-0.1101,\ Y=+0.1011#

符号:1⊕0=11\oplus0=1。

数值:

text
          1101
        × 1011
        --------
          1101
         1101
        0000
     + 1101
       --------
       10001111
[X⋅Y]原=1.10001111\boxed{[X\cdot Y]_{\text{原}}=1.10001111}

和例 2 是同一道题,把例 2 的补码结果 1.01110001 数值位取反加一,正好也是 1.10001111。