浮點數運算

2021-10-04 20:40:00 字數 3106 閱讀 8792

今天學習了浮點數運算(加減乘除)。浮點數運算主要包括兩部分:指數運算和尾數運算。在ieee754標準下,指數運算就是階碼的運算,類似於無符號數運算。尾數運算是原碼運算。之前一直很疑惑為什麼前面的教材在介紹原碼運算(加減乘除)所舉的例子都是小數運算。現在猜想那部分內容可能只是為了浮點數運算做鋪墊,這裡才是主要的內容。(當然知識是不分重點的,但考試分)。下面就來詳細介紹下浮點數運算的過程吧!另外本文使用的浮點數標準均為ieee754結構,即單精度數由1位符號位,8位指數字,23位尾數字共計32位組成。

浮點數的加減運算分為5個步驟:對階、尾數相加、尾數規格化、尾數捨入處理、溢位判斷處理。下面詳細介紹:

1. 對階:

所謂對階,就是讓兩個運算元階數相同,以便進行加減。實現的方式是對較小數的尾數進行右移操作。對階的原則是向高階看齊。計算公式為:

當結果大於0說明被加數(被減數)階數高,則對加數(減數)進行移位對階。小於0則反之改變被加數(被減數)。

2. 尾數加減:

將兩個運算元的尾數相加減。值得注意的是:在ieee754標準中,對於規格化數來說在小數點前有一位隱藏位1,在加減過程中需要把它還原到尾數中。尾數加減的實質是原碼的加減,對於原碼加減的規則如下圖所示:

3. 尾數規格化:

加減完成的尾數形式未必滿足ieee754對於尾數的要求,即保留23位,小數點在第乙個1之後。需要對尾數進行左規和右規,下面介紹一下左規和右規。

左規:將尾數向左移,用於清除第乙個1前面出現的0。左規伴隨著階碼減少,在左規過程中要檢測階碼是否發生下溢,即階碼達到最小值(0000 0000)。

右規:將尾數向右移,用於兩數相加後出現向高位進製的情況。因為兩數相加最多進一位,所以右規最多一位。右規伴隨著階碼的增加,在右規過程中要檢測階碼是否發生上溢,即階碼達到最大值(1111 1111)。

4. 尾數的捨入處理:

在對階和右規的時候,最右邊的數字會被移出。為了保證最後計算的精度,把這些數字在過程中儲存,等到最後進行捨入。也就是我上文提到的附加位。有兩個問題值得注意:

1) 保留多少附加位合適?

2)最終對附加位怎麼進行捨入?

在ieee754中保留了保護位,捨入位,粘位三位作為附加位。同時對於ieee754來說最後附加位的捨入,有如下規則:

5. 溢位判斷:

在浮點數中是以階碼的溢位與否來作為評判標準的。單精度溢位分為上溢(指數大於等於127)和下溢(指數小於等於-126)。

插一句:「之前一直以為下溢的指數是-149,這個數字**於-126再把所有的尾數向右移,當到達-149時剛剛好所有尾數全部為零,即表示零。這個誤區在於沒有正確的區分規格化數和非規格化數。對於規格化數而言,下溢就是-126,所以規格化數表示的最小值為1.00…乘2的-126次方,而0~0.111…乘2的-126次方就是非規格化數表示的範圍。-149正是非規格化數表示的最小範圍。這裡貼一張圖,更加便於理解。

下面直接貼上乙個書上的例項,對以上過程進一步加深了解:

浮點數乘除和定點數乘除相同,在正式運算前會對運算元進行預處理。對於乘法如果有乙個運算元為0則結果為0。對於浮點數除法,若被除數為0,則結果為0。除數為0分兩種情況,第一種是被除數非零,第二種是被除數為0。下面著重介紹一下兩種除數為0:

除數為0,被除數不為0:

結果為無窮大。在ieee 754標準下就是階碼全為1,尾數全為0。c語言輸出如下圖:

除數為0,被除數為0:

結果是nan(not a number)。在ieee 754標準下就是階碼全為1,尾數非0。在c語言中輸出如下圖:

注:在windows系統下,-1.#ind00即代表nan,linux系統下會輸出nan。

下面詳細介紹無特殊情況浮點數的乘除運算:

浮點數乘除運算公式如下圖:

1.浮點數的乘法:

1)尾數相乘,指數相加:

尾數相乘即為原碼相乘,這個具體的過程請參考另一篇文章:定點數運算(於文末給出**)。值得注意的是,對於規格化浮點數要記得恢復隱藏位。指數相加可以直接運用移碼的計算方法:

2)尾數規格化:

對於兩個運算元的尾數一定都是大於1的(隱藏位導致),所以最終得到的結果,小數點前會有兩位共三種情況(01,11,10)。若為01則不需規格化,11和10則需右規一位。注意對於ieee754標準浮點數乘法不需要左規。

3)尾數捨入處理:

兩個小數相乘,尾數自然更多,但位置是有限的,需要對尾數進行捨入,具體的捨入規則參照浮點數加減的捨入規則即可。

乘法的溢位有兩種可能:階碼相加減時,以及尾數右規時。右規與上文相同,下面介紹一下階碼溢位的判斷標準:

注:eb是最終的結果,ex和ey是運算元的指數值。

2.浮點數除法:

浮點數除法大致分為4步:尾數相除階相減、尾數規格化、尾數捨入、溢位判斷處理。由於除法大部分與乘法相似,所以此處只列出不同部分。

在尾數相除階相減過程中,尾數除法也在上文引用那篇文章中有具體介紹。階碼相減的運算公式如下:

在尾數規格化步驟中:當除法運算完成後,若小數點前為0,則需進行左規以保證小數點前具有隱藏位1。

對於除法階碼溢位判斷的規則如下:

注:eb為最終結果指數,exey為運算元指數。

補充:在《程式是怎樣跑起來的?》書中,對於階碼為什麼使用0-127做了乙個原因的解釋:在計算機中,使用excess系統的方法來同時儲存正數和負數。這裡面的0-127就是增加幻數之後的數字。幻數選擇了127,可記為excess_127。

本篇文章對於浮點數運算進行了介紹,因為作者水平有限,可能某些地方理解錯誤,請高手不吝賜教,批評指正,謝謝!

浮點數運算

浮點數運算的公式 n m re n代表浮點數 m代表尾數 r代表基數 e代表指數 所謂浮點數就是類似我們高中學的科學計數法 比如 1000 就表示為 1.0 103 那麼浮點型計算就是兩個用科學計數法表示的數之間進行的計算 例如 1.0 102 1.19 103 該如何計算 步驟 1.對階 所謂對階...

php 浮點數運算

php r echo 0.1 0.7 0.8 true false 了解浮點運算的都不難理解以上 執行時會得到false 這是因為很多的10進製數都不能精確的轉成2進製,或如果要精確轉換的話需要的二進位制數太長,會捨棄掉末尾部分,只儲存一定的精度。比如0.1 十進位制 0.0001100 1100 ...

浮點數的運算

規格化的浮點數因為儲存是使用類似科學計數法的表示,因此計算方法大體上與科學計數法較為類似。浮點加減法的一般步驟 減法本質也是加法 對於二進位制形式的兩個浮點數相加 1.對階 對於兩個規格化浮點數,將較小的指數的數向較大指數的數對齊。通過移動小數點實現。如果出現有效數字位數不能滿足的情況,進行近似。2...