浮點數詳解(IEEE 754標準)

在這裏插入圖片描述


【浮點數有關】
在計算機發展過程中,曾經提出過許多種實數的表達方法,比較典型的有浮點數,定點數兩種

【定點數簡介】
|| 在定點數表達法中,其小數點固定地位於實數所有數字中間的某個位置。例如,貨幣的表達就可以採用這種表達方式,如 55.00 或者 00.55 可以用於表達具有 4 位精度,小數點後有兩位的貨幣值。由於小數點位置固定,所以可以直接用 4 位數值來表達相應的數值。

|| 但我們不難發現,定點數表達法的缺點就在於其形式過於僵硬,固定的小數點位置決定了固定位數的整數部分和小數部分,不利於同時表達特別大的數或者特別小的數。因此,最終絕大多數現代的計算機系統都採納了所謂的浮點數表達法。

【浮點數簡介】
|| 浮點數表達法採用了科學計數法來表達實數,即用一個有效數字。一個基數(Base)、一個指數(Exponent)以及一個表示正負的符號來表達實數。比如,666.66 用十進制科學計數法可以表達爲 6.6666×102(其中,6.6666 爲有效數字,10 爲基數,2 爲指數)。浮點數利用指數達到了浮動小數點的效果,從而可以靈活地表達更大範圍的實數。

|| 當然,對實數的浮點表示僅作如上的規定是不夠的,因爲同一實數的浮點表示還不是唯一的。例如,上面例子中的 666.66 可以表達爲 0.66666×103、6.6666×102 或者 66.666×101 三種方式。因爲這種表達的多樣性,因此有必要對其加以規範化以達到統一表達的目標。規範的浮點數表達方式具有如下形式:
在這裏插入圖片描述(其中,d.dd…d 爲有效數字,β 爲基數,e 爲指數)

|| 有效數字中數字的個數稱爲精度,我們可以用 p 來表示,即可稱爲 p 位有效數字精度。

||十進制的基數 β 等於 10,每個數字 d 只能在 0 和 9 之間取值 , 二進制的 β 等於 2,而每個數字 d 只能在 0 和 1 之間取值。他們之間的轉換關係式(在第二步進行了十進制的運算)
在這裏插入圖片描述

|| 由上面的等式,我們可以得出:
1,向左移動二進制小數點一位相當於這個數除以 2,而向右移動二進制小數點一位相當於這個數乘2。如 101.11=3/4,而 10.111=7/8。
2,一個十進制小數要能用浮點數精確地表示,最後一位必爲5(當然這是必要條件,並非充分條件)
可以使用程序證明:

#include <stdio.h>
int main(void)
{
    float f1=34.6;
    float f2=34.5;
    float f3=34.0;
    printf("34.6-34.0=%f\n",f1-f3);
    printf("34.5-34.0=%f\n",f2-f3);
    return 0;
}

|| 誤差原理:因爲計算機將二進制轉換爲十進制的浮點數時,若十進制浮點數尾數非5/0,會因爲二進制數無法精確轉化爲該數而保存四捨五入的結果,故造成了誤差,如下圖:

在這裏插入圖片描述

因此,建議不要將浮點數用於精確計算!!!
且建議不要將浮點數直接用 == 或 != 進行比較,儘量轉換爲><號

#include <stdio.h>
int main(void)
{
    float f1=34.7;
   	if(f1 - 34.7 < 0.001) 
    	printf("Right!");
	
	if(f1 == 34.7)
		printf("Right!");
	
    return 0;
}

【IEEE浮點數表示法】

|| 本質:IEEE 浮點數標準是從邏輯上用三元組{S,E,M}來表示一個浮點數 V 的,即 V=(-1)S×M×2E
在這裏插入圖片描述

  • 符號位 s(Sign)決定數是正數(s=0)還是負數(s=1),而對於數值 0 的符號位解釋則作爲特殊情況處理。

  • 有效數字位 M(Significand)是二進制小數,它的取值範圍爲 1~2-ε,或者爲
    0~1-ε。它也被稱爲尾數位(Mantissa)、係數位(Coefficient),甚至還被稱作“小數”。

  • 指數位E(Exponent)是 2 的冪(可能是負數),它的作用是對浮點數加權。

||(分析思路:位數 = =》 有效範圍 = =》實際範圍 )

【32位單精度浮點數詳解】

Float
S--------E-------M
1位-----8位-----23位

M位:代表其精度,有效數字的個數有 2^ (23+1) = 16777216個,即二進制數的範圍爲(0,16777216) 化爲十進制:10^ 7 < 16777216 < 10^8,所以說單精度浮點數的有效位數是7位

E位:代表其指數位:有效數字個數有 2^ 8 = 256個,即指數範圍爲(0,255)除去第一個和最後一個數字作爲特殊值,有效指數的範圍爲(1,254),設置一個偏差值(2k-1-1)= -127 使之可以表示負指數,故實際指數範圍(-126,127),可以代表127個正指數和126個負指數加1個零指數。

【64位雙精度浮點數詳解】

Double
S--------E-------M
1位-----11位----52位

M位:代表其精度,有效數字個數有*2^ (52+1) = 9007199254740992,又10^ 16 < 9007199254740992 < 10^17,所以雙精度的有效位數是16位
E位:代表其指數位:有效數字個數有 2^ 11 = 2048個,即指數範圍爲(0,2047)除去第一個和最後一個數字作爲特殊值,有效指數的範圍爲(1,2046),設置一個偏差值(2k-1-1)= 1023 使之可以表示負指數,故實際指數範圍(-1022,1023),可以代表1023個正指數和11022個負指數加1個零指數。

|| 浮點異常值:NAN,QNAN,SNAN
這裏所要說的浮點異常值就是這種IEEE浮點表示產生的幾種特殊值,IEEE規定根據指數和尾數的不同分別可表示如下幾種特殊值:

  1. 零值:按上述的浮點表述形式如果指數部分全部爲0,並且尾數全部爲0,則表示爲浮點0.0,並且規定-0 = +0

  2. 非規格化值:如果指數全部爲0,尾數非0,則表示非規格化的值,16進制看到的就是[80xxxxxx]h或者[00xxxxxx]h

  3. 無窮值:如果指數全部爲1,尾數全部爲0,則根據符號位分別表示正無窮大和負無窮大,16進制看到的就是[FF800000]h或者[7F800000]h

  4. NAN:如果指數全部爲1,尾數非0,則表示這個值不是一個真正的值(Not A Number)。NAN又分成兩類:QNAN(Quiet NAN)和SNAN(Singaling NAN)。
    QNAN與SNAN的不同之處在於,QNAN的尾數部分最高位定義爲1,SNAN最高位定義爲0;
    QNAN一般表示未定義的算術運算結果(技術NaN),最常見的莫過於除0運算;SNAN一般被用於標記未初始化的值 (信號NaN),以此來捕獲異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章