定点数运算
??????本篇文章討論定點數的運算。因作者水平有限,本文只討論補碼加減運算、原碼加減運算、原碼1位乘法運算、原碼除法。其余運算請參照其他高手的文章。下面我們開始吧!
運算硬件結構:
??????在計算機中,加減乘除四種運算實質上是由加法器和移位器組合完成。本文為便于讀者了解,在過程中附帶了幾張進行加減乘除運算的硬件結構圖。
??????對于無符號數來說,只存在進位借位,溢出沒有意義(在此訂正:對于無符號數而言,存在下溢,即兩個數相減,結果被被減數還要大,即發生下溢。判斷條件為CF為1)。對于有符號來說,每次進行運算時都要判斷是否發生溢出。
1. 補碼加減運算:
??????補碼加減的運算公式如下:
??????運算部件:
??????運算部件介紹:
?????????X,Y為兩個輸入,其中Y為加數,X為被加數。
???????? Sub代表是否具有減法運算(sub為1時為減法,為0時為加法)。 ZF(zero flag)代表結果是否為零(ZF為1時結果為0,為0時結果非零)。
????????OF(overflow flag)代表是否發生了溢出(OF為1是溢出,為0時未溢出)。注意此位對于帶符號運算有意義,無符號運算無意義。
????????SF(sign flag)代表結果的符號(SF為1代表負數,為0代表正數),注意此位對于帶符號運算有意義,無符號運算無意義。
????????CF(借/進位 flag)代表無符號數運算是否發生進位(加法)、借位(減法)。(CF為1代表加法有進位,減法有借位,為0代表運算正常)。 注意此位對于無符號運算有意義,帶符號運算無意義。
??????對于補碼加減法而言,將加數和被加數全部轉換成補碼進行運算即可,(減法轉變成加上相反數的補碼)。重點在于對是否溢出做判斷。無符號數的加減可以看作是正數補碼的加減(對于正數來說,補碼為其本身,并沒有改變數值,但此處不是十分確定,歡迎高手批評指正),故也能使用這種運算部件來判斷。
?????? 設運算數為a,b和為c:
??????一個比較簡單的方式就是:由于前后加減運算要求位數相同,如果a,b的符號位均為0或1,而c的符號與兩者相反,則此時一定發生溢出。(通俗的解釋就是正數加正數結果不可能為負數,負數加負數(負數減正數)結果也不可能為正數)。但計算機不能像人類這樣直觀的判斷,它憑借的還是前文所介紹運算結構的輸出,憑借以下兩種邏輯表達式進行判斷:
??????下面結合一個具體例子進行分析:
??????C(n)代表符號位進位,也是最高位進位,若未進位則此位為0。C(n-1)代表非符號最高位進位,若未進位為0。這兩個例子滿足兩個邏輯表達式。
2. 原碼加減:
??????原碼加減沒有補碼加減應用廣泛,原碼加減主要應用在浮點數做加減。原因是浮點數的尾數使用原碼表示。本文主要介紹定點數,對此貼張圖說明運算規則即可:
3. 原碼1位乘法:
??????運算結構如圖:
??????運算結構介紹:初始化被乘數在寄存器X中,對于N乘N來說結果是2N位。乘積寄存器P存儲結果高32位,寄存器Y原存儲乘數后存儲結果低32位。
??????值得注意的是對于乘法運算來說,任意一個乘數為0結果為0.所以在正式運算開始之前會進行一個預判,若有任意一個為0,則直接結果設置為0。同時兩個n位數相乘,所得結果為2n位。運算結束后,高n位為0表示正常,只保留低n位作為乘積結果。如果高n位不為0,則表示n位運算溢出。
??????結果的符號位由乘數及被乘數的符號位異或運算可得。本文主要介紹最終結果是如何得到的。
??????手寫的過程如下:
??????根據手寫的規律看,隨著每位的乘法,結果不斷向左移。
??????在計算機執行中,做了相應的一點改變以優化效率。為了減少對于過程中變量的存儲,選擇了保留部分積,即每次運算都在上一步得到的結果上進行操作。同時對變左移為對部分積的右移。若乘數位為1則加上被乘數后進行右移,若乘數為0則直接進行右移。下面結合一個具體的例子來進行分析:
??????例題中可知,符號位C即為和的進位,同時也作為P右移的補位,P中最低位進入Y中作為最高位。本題中只有四位,所以右移四位即可。在實際計算機中,右移的位數由計數器控制。
4. 原碼除法:
??????除法有規定,除數不能為零。所以計算機在執行過程中會先進行一個預處理,判斷如果除數為0,對于定點數來說C語言中會直接拋出異常。如果被除數為0,則直接輸出0。商的符號位是由兩數符號位異或操作獲得。
?????? 下面附帶一章代碼實例運行的圖說明定點數除數不可為0問題(輸出為空,拋出異常):
??????運算結構如圖:
??????運算結構介紹:
?????????為了保證結果和輸入位數相同,對被除數做擴張至位數為2n。除數存儲在寄存器Y中,余數和商作為最終結果存儲在一起。在擴展的過程中如果是整數,在高位添加n個0。如果是小數,在低位添加n個0。(一定要記住,不要搞反)
?????????在手算除法中,每步都要進行一次嘗試,看目前的結果能否足夠除以除數,夠除商上1并將兩數做減。不夠除上0,除數右移。稱之為“上商”。具體手算過程如圖:
??????在計算機中,原除數右移變為固定除數而被除數左移。所以整個過程由加法和左移兩部分完成。
??????計算除法大致方法分為兩種:恢復余數法和加減交替法。兩種方法從原理上看,是相同的。只是對等式做了變形。下面對兩種方法進行具體介紹:
1)恢復余數法:
??????當部分商與除數做減后小于0,說明當前部分上不夠減需要向左移。那么先將減去的除數加回來恢復上一步的部分商再左移。如此循環下去,直到左移位數達到除數的位數即止。下面根據一個具體例子來進行分析:
??????本題是兩個小數之間進行除法運算,包括符號位共有5位,做擴展即在低位擴展5位。當每次和符號位為1時,則恢復余數后左移。整體共左移4次,最后一位補位即可不需左移。
2) 加減交替法:
??????加減交替法是根據部分商的正負決定是加Y還是減Y,當部分商小于0時則加Y,當部分商大于零時則減Y。這里的部分商指的是移位之前的部分商。每次進行完加法后先進行移位,在加或者減,下面結合上文提到的例子來分析:
??????在本例中每次加法過后,則進行加Y/減Y。最終四次移位五次補位后得到結論。
??????在本文末尾介紹一下異常:
異常不同于BUG,是無法被編譯器檢驗出來的。會通過不合理的輸出反應。異常出現的幾種情況:
??????1)定點數運行時產生除零的情況
??????2)需要打開的文件不存在
??????3)數組訪問時越界
??????對異常部分參照博客:https://blog.csdn.net/small_prince_/article/details/80533159link
??????本文介紹的定點數運算至關重要,它直接關系到浮點數的正常運算。只有理解定點數,才能更好的明白浮點數。加油呦~
總結
- 上一篇: 关于Linux C multiple d
- 下一篇: Windows驱动—VS2010+WDK