《電子技術應用》
您所在的位置:首頁 > 嵌入式技術 > 解決方案 > 計算機系統(tǒng)原理(九) 二進制整數(shù)的加法運算和減法運算

計算機系統(tǒng)原理(九) 二進制整數(shù)的加法運算和減法運算

2017-06-22
關鍵詞: 匯編語言

引言

平時的編程過程中,當進行整數(shù)運算時,經(jīng)常會遇到一些奇怪的結(jié)果,比如兩個正數(shù)加出負數(shù),兩個負數(shù)可以加出一個正數(shù),這些都是由于數(shù)值表示的有限性導致的。下面我們來看看C語言和Java語言當中的例子。

public static void main(String[] args) {
       int a = 0x7FFFFFFF;
       int b = 0x7FFFFFFF;
       System.out.println(a);
       System.out.println(b);
       System.out.println( a + b );
   }

程序當中的a和b都是很大的正整數(shù),結(jié)果它們相加會得到一個負數(shù)。

接下來我們再來看看C語言當中的例子,它也會具有同樣的特性。

#include <stdio.h>
   
int main(){
   int a = 0x7FFFFFFF;
   int b = 0x7FFFFFFF;
   printf("%d\n",a);
   printf("%d\n",b);
   printf("%d\n",a+b);
}


我們來看看這個程序的結(jié)果,是否與Java一致。

可以看到,在C于Java當中,結(jié)果都是一樣的,所以我們有必要對二進制整數(shù)的運算做一些簡單的了解。

無符號加法

這里LZ不想按照書中的方式去介紹,我們換一種思路,來簡單的了解一下吧。

小時候?qū)W習加法時,我們都是使用的畫表式,就是上面是被加數(shù),下面是加數(shù),然后左邊寫一個加號,逢10就進1,然后下面畫一條橫線,橫線下面就是我們的結(jié)果。

對于我們的二進制整數(shù)來說,其實也可以使用這種最原始的方式去計算,由此也可以認識到,二進制整數(shù)的加法也是非常簡單的。只不過它與我們平時的十進制算法有一個最大的區(qū)別,那就是我們在計算機當中進行計算時,結(jié)果的位數(shù)都是有限制的。因此在我們計算過后,可能需要對結(jié)果進行截斷操作。

前面一章我們已經(jīng)講過有關截斷的內(nèi)容,那么很明顯這里就可以用上了。這里使用的時候有一個前提,我們可以假設是進行w位的二進制運算,那么在運算之后的實際結(jié)果也一定是w位的。這里有兩種情況,一種是結(jié)果依然是w位的,也就是w+1位為0。第二種則是達到了w+1位,這個時候我們需要將結(jié)果截斷到w位。

第一種情況則屬于正常的加法運算,對于第二種來說,我們根據(jù)上一章的結(jié)論可以得到,假設完整的結(jié)果為sum,則實際的結(jié)果最終為 sum mod 2w。

在書中則是給出了一個公式,它得到這個結(jié)果的一個前提是兩個操作數(shù)都滿足小于2w,它與我們上面取模的結(jié)果其實是一樣的。

這里LZ再稍微解釋一下,對于第一種情況,x+y < 2w,則sum mod 2w是與sum一致的。對于第二種來說,當 2w =< x+y < 2w+1,對 x + y 進行2w的取模運算,與 x + y - 2w是等價的。

無符號的非

無符號的加法會形成一個阿貝爾群,這意味著無符號加法滿足一些特性。比如可交換,可結(jié)合等等。在這個群中,單位元為0,那么每一個群中的元素,也就是每一個無符號數(shù)u,都會擁有一個逆元u-1,滿足 u+ u-1 = 0。這個結(jié)論的來源是,對于w位上的無符號運算來講,倘若兩個無符號數(shù)的加法運算結(jié)果為2w,也就是1后面跟w個0,此時截斷之后的結(jié)果則為0。

從以上的簡單分析,我們可以很容易的得到一個無符號數(shù)的逆元滿足以下公式(公式中的左邊就是LZ寫的u-1,由于圖中的符號在博文中不好編輯,所以LZ以u-1替代)。

補碼加法

對于補碼的加法來講,我們會建立在無符號加法的基礎上來進行,這么做的一個重要前提是,它們的位表示都是一樣的。

這里書上寫的比較復雜,LZ這里稍微介紹的簡單一點,其實補碼加法就是先按照無符號加法進行運算,而后在進行無符號和有符號的轉(zhuǎn)換。因此我們根據(jù)上面的結(jié)論可以得到,對于兩個補碼編碼的有符號數(shù)來說,他們進行加法運算的最終結(jié)果為,假設實際的無符號結(jié)果為sum,那么最終的實際結(jié)果為 U2Tw(sum mod 2w)。

上面的這個結(jié)果看起來很簡單,但實際上它的運算結(jié)果還是比較復雜的,書中給出了四種情況的分析,采用數(shù)學推導和證明的方式來說明,估計對一部分數(shù)學基礎較差的猿友來講,這是一種折磨,因此LZ這里將會省去這部分分析,如果有興趣的猿友可以私底下看一下書中的原版內(nèi)容。

與無符號加法不同的是,這里會出現(xiàn)三種結(jié)果,一種是正常的結(jié)果,一種是正溢出,一種是負溢出。

對于當正溢出的時候,我們的結(jié)果與無符號數(shù)類似,取模之后等價于減去2w。而當負溢出的時候,則剛好相反,取模之后的結(jié)果等價于加上2w。更直觀的,由于我們最終可表示的補碼數(shù)范圍在-2w-1(包含)到2w-1之間,所以我們總是要試圖將最終的實際結(jié)果保持在這個范圍之內(nèi)。于是我們可以直觀的得到下面的結(jié)果。

補碼的非

對于補碼來說,它同樣的與無符號有一樣的特性,也就是對于任意一個w位的補碼數(shù)t來說,它都有唯一的逆元t-1,使得t + t-1 = 0。

一個w位的補碼數(shù)的范圍在-2w-1(包含)到2w-1之間,直觀的可以看出,對于不等于-2w-1的補碼數(shù)x來說,它的逆元就是-x。而對于-2w-1來說,它的二進制位表示為1后面跟著w-1個0,我們需要找到一個數(shù)與其相加之后結(jié)果為0。

這種時候我們需要考慮的是,如果是-x,也就是2w-1,則它的位表示需要w+1位,是不存在的。因此我們需要考慮溢出的情況,對照上面的公式2.14,負溢出的時候需要加上2w,因此-2w-1的逆元就是-2w + 2w-1 = -2w-1,也就是它本身。

綜合上面的情況,最終我們可以得到補碼的逆元滿足以下公式(這里與上面一樣,公式左邊是LZ所說的逆元t-1)。

二進制整數(shù)的減法

這一部分內(nèi)容在書中沒有介紹,而且書中也沒有提及為什么沒有介紹,因此LZ在這里簡單的提上幾句。

減法運算其實是可以由加法運算替代的,我們上面已經(jīng)介紹過了無符號和補碼的非,其實很多CPU是沒有減法運算器的,它們都是將減數(shù)進行逆運算以后送入加法器,然后進行加法運算,這樣得出來的結(jié)果就是減法運算最終的結(jié)果。

比如我們考慮一種簡單的情況,當w = 4時的無符號減法運算,對于 5 - 4這個減法運算來說,我們可以由 5 + 4-1(其中4-1是4的逆元的意思,不是1/4的意思)來替代這個減法運算。

為了更加直觀,LZ帶各位來算一下,首先4的逆元根據(jù)上面的公式可以得到為 4-1 = 24 - 4 = 12 。那么我們現(xiàn)在需要對5和12進行加法運算,它們的位表示分別為 0101和1100,結(jié)果為10001,也就是十進制17的位表示。不過由于我們的w = 4,因此截斷之后結(jié)果為0001,也就是十進制的1。最終可以得到 5 - 4 = 1。

對于5 - 4來說,是考慮的結(jié)果為正的情況?;蛟S有的猿友會對結(jié)果為負或者說是無符號數(shù)溢出的情況下有疑問,因此LZ這里對這種情況也做一個簡單的介紹。我們考慮一個簡單的計算 0 - 1,我們可以得到1-1 = 24 - 1 = 15。此時對0和15進行加法運算,他們的位表示分別為0000和1111,結(jié)果為1111。

看到這里估計有的猿友會奇怪了,這怎么回事,0 - 1 = 15?

當然不是,這個結(jié)果其實是正確的。考慮使用補碼編碼來解析1111這個位表示,它代表的值就是-1。15是1111這個位表示在無符號編碼情況下的解析結(jié)果。

因此LZ這里也給出一個公式,就是對于兩個整數(shù)x和y來說,x - y = x + y-1。這里需要特別說明的是,這個公式代表的意義是位表示,而不是實際的數(shù)值。

文章小結(jié)

本次我們主要介紹了二進制整數(shù)的加法運算,除此之外LZ還多加了一部分,就是減法的簡單介紹。下一章我們將繼續(xù)講解整數(shù)的乘除法運算。


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權者。如涉及作品內(nèi)容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。