這個學期一直上網課,全都是看視頻,所以沒看過書。對於一些知識點只是看PPT理解,所以有很多知識點不知其所以然,最近復習開始看書才發現其中的奧妙,簡直是妙不可言。
以下內容來自《計算機組成原理》唐朔飛的教材。
手算乘法對於接受過義務教育的我們應該不是問題,那么我就直接上手算二進制乘法的改進版。
手算二進制的改進
設\(A=0.1101\),\(B=0.1011\),求\(A×B\)。
\[\begin{aligned}A \cdot B &=A \cdot 0.1011 \\&=0.1 A+0.00 A+0.001 A+0.0001 A \\&=0.1 A+0.00 A+0.001(A+0.1 A) \\&=0.1 A+0.01[0 A+0.1(A+0.1 A)] \\&=0.1\{A+0.1[0 A+0.1(A+0.1 A)]\} \\&=2^{-1}\left\{A+2^{-1}\left[0 A+2^{-1}\left(A+2^{-1} A\right)\right]\right\} \\&=2^{-1}\left\{A+2^{-1}\left[0 A+2^{-1}\left(A+2^{-1}(A+0)\right)\right]\right\}\end{aligned} \]
通過上式可見,兩數相乘的過程,可以視為加法和位移兩種運算,這對計算機來說是非常容易實現的。
下圖是具體實現的計算步驟:

實現上述步驟需要用一個寄存器存放被乘數,一個寄存器存放乘積的高位,另一個寄存器存放乘數和乘積的低位。
原碼一位乘法
由於原碼與真值之間只相差一個符號,而乘積的符號又可通過兩數符號的邏輯異或求得,所以上述運算可直接用於原碼一位乘,只需要對符號位進行處理就行了。
原碼一位乘運算規則:
\[[x]_原 = x_{0}.x_{1} x_{2} \cdots x_{n} \]
\[[y]_原 = y_{0}.y_{1} y_{2} \cdots y_{n} \]
\[[x]_原·[y]_原=x_0\oplus y_0(0.x_1x_2\cdots x_n)(0.y_{0}.y_{1} y_{2} \cdots y_{n}) \]
式中\(0 . x_{1} x_{2} \cdots x_{n}\)和\(0 . y_{1} y_{2} \cdots y_{n}\)是x和y的絕對值,記作\(x^*\)和\(y^*\)。
補碼一位乘法
被乘數\([x]_補 = x_{0}.x_{1} x_{2} \cdots x_{n}\),乘數\([y]_補 = y_{0}.y_{1} y_{2} \cdots y_{n}\)。
- 被乘數x符號任意,乘數y符號為正
\[\begin{equation}\begin{array}{l}{[x]_{\text {補 }}=x_{0} \cdot x_{1} x_{2} \cdots x_{n}=2+x=2^{n+1}+x\ \ (\bmod 2\ )} \\{[y]_{\text {補 }}=0 . y_{1} y_{2} \cdots y_{n}=y} \\{[x]_{\text {補 }} \cdot[y]_{\text {補 }}=[x]_{\text {補 }} \cdot y=\left(2^{n+1}+x\right) \cdot y=2^{n+1} \cdot y+x y}\end{array}\end{equation} \]
下面這一串等式很重要,一定要看懂:
\[\begin{equation}y=0 . y_{1} y_{2} \cdots y_{n}=\sum_{i=1}^{n} y_{i} 2^{-i}, \text { 則 } 2^{n+1} \cdot y=2 \sum_{i=1}^{n} y_{i} 2^{n-i}\end{equation} \]
按照我的理解:\(y_i\)中至少有一個為1,否則\(y=0\),而且\(n≥i\),所以\(2^{n-i}≥1\),可得到\(\sum_{i=1}^{n}y_i2^{n-i}≥1\),進而\(2 \sum_{i=1}^{n} y_{i} 2^{n-i}\)的結果是2的整數倍,所以有 \(2^{n+1}·y=2(\bmod2)\)。
則:
\[[x]_{\text {補 }} \cdot[y]_{\text {補 }}=2^{n+1} \cdot y+x y=2+x y=[x \cdot y]_{\text {補 }} \quad(\bmod 2) \]
即:
\[[x \cdot y]_{\text {補 }}=[x]_{\text {補 }} \cdot[y]_{補}=[x]_{\text {補 }} \cdot y \]
- 被乘數x任意符號,乘數y符號為負
\[\begin{equation}\begin{array}{l}{[x]_{\text {補 }}=x_{0} \cdot x_{1} x_{2} \cdots x_{n}} \\{[y]_{\text {補 }}=1 \cdot y_{1} y_{2} \cdots y_{n}=2+y(\bmod 2)}\end{array}\end{equation} \]
則:
\[\begin{equation}\begin{aligned}y &=[y]_{\text {補 }}-2=1 . y_{1} y_{2} \cdots y_{n}-2=0 . y_{1} y_{2} \cdots y_{n}-1 \\x \cdot y &=x\left(0 . y_{1} y_{2} \cdots y_{n}-1\right) \\&=x\left(0 . y_{1} y_{2} \cdots y_{n}\right)-x\end{aligned}\end{equation} \]
故:
\[\begin{equation}[x \cdot y]_{\text {補 }}=\left[x\left(0 . y_{1} y_{2} \cdots y_{n}\right)\right]_{\text {補 }}+[-x]_{\text {補 }}\end{equation} \]
將\(0 . y_{1} y_{2} \cdots y_{n}\)視為一個正數,正好與上述情況相同。所以:
\[\begin{equation}[x \cdot y]_{\text {補 }}=[x]_{\text {補 }}\left(0 . y_{1} y_{2} \cdots y_{n}\right)+[-x]_{\text {補 }}\end{equation} \]
乘數為負的補碼乘法與乘數為正的乘法類似,只需最后加上一項校正項\(-[x]_補\)即可。
需要注意的是:在相加和移位時要按照補碼規則進行。