【基礎知識】CPU原理之減法、乘法和除法


 中介紹了布爾邏輯、數學和電路的關系,我們也得到了與門、或門、非門、或非門、與非門、異或門等門電路以及一個加法器,並且了解了計算機是如何做加法的,這篇文章介紹一下計算機是如何做減法以及乘除法的

 

 

0x01

減法

 

我們先看一下十進制里減法怎么做,存在什么問題?

457減368個位數7減8是不夠減的,所以需要向十位借位,17減8等於9。5變成4,4減6又是不夠減,向百位借位,14減6等於8。百位3減3等於0,結果是89。這個是我們自己計算減法時候一種很通用的方法,這種方法用計算機處理有兩個問題。一個問題是借位,另一個問題是需要掌握20以內的減法。之前的機械計算機減法確實也是這么做的,不過隨着歷史的車輪滾滾前行,計算機的發展過程中人才輩出,還是有人發現了另外一種計算減法的簡單方法-補碼,成功的把減法當成了加法來處理。

 

我們來看一下,457 – 368等於457 + (1000 – 368) – 1000。1000 – 368等於632。632就是368在10進制數里的補碼。457+632 = 1089,減去剛才的1000,可不就是89嗎?但是這里可能有人會問計算補碼不還是得計算1000減368,沒解決根本問題啊。但是在二進制里,計算起來就方便多了(二進制真是化簡為繁的重大發現)。其實對於一個只能計算三位數的計算機來講,負368計算補碼的正確方式999-368+1。因為三位數的計算機表示不了1000。對於二進制來講,那就是先取反,再加一,取反用非門就可以搞定了。計算機里有符號數用高位表示符號,1是負數,0是正數,所以-1在計算機里用二進制的表示應該是1 1 1 1 1 1 1 1,對應的無符號數是255。

 

0x02

乘法

 

視頻:https://zh.coursera.org/lecture/jisuanji-zucheng/402-cheng-fa-qi-de-shi-xian-lp2kEc

乘法怎么算呢?同樣我們先看下十進制乘法123 * 321是怎么計算的。

 

 

123 * 321 = 123 *(3 * 100 + 2 * 10 + 1)=  (123 * 3) * 100 + (123 * 2) * 10 + 123 = 36900 + 2460 + 123 = 39483。

 

這樣就轉化為乘法、左移和加法操作。有的同學可能又會問,123 * 3計算機怎么算?先別動手,我們還有二進制,最終的乘法其實已經被簡化為被乘數乘以10以內的數,在二進制里,那就是被乘數乘以2以內的數,2以內的數只有0和1,是不是就簡單多了。我們看下11 * 12的二進制數相乘的計算過程。

 

1011 * 1100 = 1011 * 0 + 10110(1011左移一位)* 0 + 101100(1011左移兩位)* 1 + 1011000(1011左移三位)* 1 。這下是不是簡單多了,不是乘以0就是乘以1,最后通過加法器相加就好了。

 

public class Multiplier {
    /**
     * 模擬計算機乘法器兩數相乘的過程:
     * 1.數學上m * n表示n個m相加
     * 2.但計算機乘法器是二進制的,m乘以n中第i位不為0的比特位意味着m向左移動i位,把所有這樣的結果相加,即為乘法器的計算過程
     * @param m 被乘數
     * @param n 乘數
     * @return 積
     */
    public static long multiply(int m, int n) {
        if (m == 0 || n == 0)
            return 0;
 
        long result = 0;
        // 獲取乘數從最高比特位往低比特位第一個不為零的比特位之間0比特位的數量
        int loop = 64 - Long.numberOfLeadingZeros(n);
        for (int i = 0; i < loop; i++) {
            if (((1 << i) & n) != 0)
                result += m << i;
        }
        return result;
    }
}

 

 

 

 

 

0x03

除法

 

乘法搞定了,就差除法了,除法怎么算呢?老規矩,我們先看下10進制123除以4的計算方法。

 

 

123 最高位1,比4小,結果是0,余數是1;

12上一步的余數1左移1位是10,加上2是12,12除以4等於3,余數是0;

12最后一位是3,比4小,結果是0,余數是3。

所以結果是30,余數是3。

沒毛病,讓我們看下二進制計算的過程。

 

 

1 1 1 1 0 1 1 中的1 比 100小,結果是0,余數是1。

1 1 1 1 0 1 1 上一步中的余數1左移1位,加上1是11,比100小,結果是0,余數是11。

1 1 1 1 0 1 1 上一步中的余數11左移1位,加上1是111,比100大,結果是1,余數是11。

1 1 1 1 0 1 1 上一步中的余數11左移1位,加上1是111,比100大,結果是1,余數是11。

1 1 1 1 0 1 1 上一步中的余數11左移1位,加上0是110,比100大,結果是1,余數是10。

1 1 1 1 0 1 1 上一步中的余數10左移1位,加上1是101,比100大,結果是1,余數是1。

1 1 1 1 0 1 1 上一步中的余數1左移1位,加上1是11,比100小,結果是0,余數是11。

 

所以結果是0011110(十進制30),余數是11(十進制數3)。

 

 

0xff

總結

 

加法是計算機中最基本的操作,我們已經有了加法器,計算加法毫無壓力。減法則通過補碼,巧妙的轉化成了加法的運算。而乘法是通過左移和加法完成的,除法則是通過左移和減法完成的。我們通過加法器以及移位器就能完成基本的加減乘除算術運算。但是這樣只能完成兩個數的操作,如果想完成三個數的操作怎么辦呢?總不能計算兩個數,人工記錄下來結果,然后再與第三個數相加吧,這就需要另外一個東西-寄存器了,有了寄存器,計算機就可以暫存一些中間結果,持續的執行代碼進行計算了。下篇文章,給大家分享一下通過電路怎么記錄數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM