跳转至

Chapter 3 Part 3: 算术运算

(共 49 页)

二进制整数乘法(无符号)

$A \times B$,先不考虑交换律,把 $A$ 称作 multiplicand(被乘数),把 $B$ 称作 multiplier(乘数)。对于乘数的每一位($i \in [0, w-1]$)分别考虑:

  • 若第 $i$ 位是 $1$,答案就加上 $A$ 左移 $i$ 位
  • 若第 $i$ 位是 $0$,答案不变

image-20221201221345751

相当于列竖式计算。

事实上,把答案右移保留尾位、再把 $A$ 加给答案的最高位,得到结果也是一样的,但是比较麻烦。

硬件二进制整数乘法(无符号)

image-20221201222941564

实现 $4$ 位二进制乘法的硬件组合如图所示。将累加器 $Acc$ 和寄存器 $R_1$ 串联起来,得到了一个八位右移寄存器。由于两个 $4$ 位二进制数相乘,得到的结果最大就是 $8$ 位二进制,所以这个八位右移寄存器可以用于存储答案。此外,存在一个加法器 $Adder$,以 $Acc$ 和 $R_2$ 作为输入,再把输出(加法结果)传送给 $Acc$。

运算过程是:

  1. $Acc$ 初值赋零。$R_2$ 赋初值为被乘数,$R_1$ 赋为乘数。
  2. 如果 $R_1$ 的最低位是 $1$,就把 $R_2$ 和 $Acc$ 做一次加法,结果存储给 $Acc$。
  3. 八位寄存器 $[Acc, R_1]$ 整体右移。
  4. 第二、三步,重复 $4$ 次。
  5. 最终,八位寄存器整体的值就是答案。用(伪)程序语言来描述就是:
uint8_t mul(uint4_t R_1, uint4_t R_2) {
  // R_2 * R_1
  uint4_t Acc = 0;
  for (int i = 0; i < 4; ++i) {
    if (R_1 & 1) Acc += R_2;
    R_1 >>= 1;
    R_1 += (Acc & 1) << (4 - 1);
    Acc >>= 1;
  }
  return (Acc << 4) + R_1;
}

下图逐步描述了 $1011 + 0101$ 的硬件级运算过程。

image-20221201223957773

有符号怎么办?

课件上没有说直接当成补码运算是否可行。但是说,可以把符号去掉,运算完之后再加上符号。

二进制整数除法(无符号)

依然是列竖式。但是除法的竖式计算比较麻烦。

暂时用 $\div$ 表示整数除法。设 $A \div B = C \dots D$,称:$A$ 是 dividend(被除数),$B$ 是 divisor(除数),$C$ 是 quotient(商),$D$ 是 reminder(余数)

硬件二进制整数除法(无符号)

结构类似于硬件二进制整数乘法。

注意,对于 $w$ 位二进制无符号整数除法,需要使用三个 $w+1$ 位的寄存器,这一点与只需要 $w$ 位寄存器的乘法有区别。因为需要用额外的一个 bit 来表示执行减法后是否会导致结果小于零(我们还没学如何比较两个二进制数的大小。如果 $A-B<0$ 就表示 $A<B$,而有符号加减法可以直接用补码实现。如果相减得到结果小于零,就撤销这次减法操作,往后一位重新尝试减法)。这里的硬件与乘法还有一点不同,乘法是 $[Acc, R_1]$ 整体右移,除法是 $[Acc, R_1]$ 整体左移

image-20221201232706083

当被除数 $\geq$ 除数,则执行运算过程:

  1. $Acc$ 赋初值为被除数 dividend。$R_2$ 赋值为除数,$R_1$ 赋值为零。
  2. 把 $R_2$ 的最高位与 $Acc$ 对齐(仅需第一次减法前进行一次对齐)
  3. 从 $Acc$ 中减去 $R_2$
  4. 若 $Acc < 0$
  5. 把 $R_2$ 加回去 $Acc$(撤销减法)
  6. 把 $[Acc, R_1]$ 整体左移,右侧补零
  7. 若 $Acc \geq 0$
  8. 把 $[Acc, R_1]$ 整体左移,右侧补一
  9. 重复数次上述过程(3,4,5)。~~重复几次,没看懂~~
  10. 最终 $Acc$ 中存储的是余数(~~可能还需右移几次,没看懂~~),而答案(商)存储在 $R_1$ 中。

浮点数

25 页开始

IEEE 754

对于 32 位浮点数(正),表示的范围是:$2^{-149} \sim (1-2^{-23}) \times 2^{126}$。咋算出来的不是很懂。数学真奇妙。

浮点数加减法

浮点数乘除法

硬件浮点数性能