浮點數表示

2021-07-25 13:34:26 字數 3945 閱讀 3935

之前的一些工作當中碰到了很多有關浮點數的問題,比如浮點數的表達範圍、表達精度、浮點數的儲存方式、浮點數的強制型別轉換等等,因此感覺有必要系統了解一下有關浮點數的問題。

浮點數是一種公式化的表達方式,用來近似表示實數,並且可以在表達範圍和表示精度之間進行權衡(因此被稱為浮點數)。

浮點數通常被表示為:

\(n = m\times r^e\)

比如: \(12.345 = 1.2345\times 10^1\)

其中,m(mantissa)被稱為浮點數的尾數,r(radix)被稱為階碼的基數,e(exponent)被稱為階的階碼。計算機中一般規定r為2、8或16,是乙個確定的常數,不需要在浮點數中明確表示出來。

因此,在已知標準下,要表示浮點數,

一是要給出尾數m的值,通常用定點小數形式表示,它決定了浮點數的表示精度,即可以給出的有效數字的位數。

二是要給出階碼,通常用定點整數形式表示,它指出的是小數點在資料中的位置,決定了浮點數的表示範圍。因此,在計算機中,浮點數通常被表示成如下格式:(假定為32位浮點數,基為2,其中最高位為符號位)

按照上面的指數表示方法,乙個浮點數會有不同的表示:

\(0.3\times10^0\);\(0.03\times10^1\);\(0.003\times10^2\);\(0.0003\times10^3\);

為了提高資料的表示精度同時保證資料表示的唯一性,需要對浮點數做規格化處理。

在計算機內,對非0值的浮點數,要求尾數的絕對值必須大於基數的倒數,即\(|m|\ge \frac\)。

即要求尾數域的最高有效位應為1,稱滿足這種表示要求的浮點數為規格化表示:把不滿足這一表示要求的尾數,變成滿足這一要求的尾數的操作過程,叫作浮點數的規格化處理,通過尾數移位和修改階碼實現。

比如,二進位制原碼的規格化數的表現形式:(0正1負)

正數0.1******

負數1.1******

注意,尾數的最高位始終是1,因此我們完全可以省略掉該位。

至此,我們引入ieee754 標準,該標準約束了浮點數的大部分使用設定:(尾數用原碼;階碼用「移碼」;基為2)

(1) 尾數用原碼,且隱藏尾數最高位。

原碼非0值浮點數的尾數數值最高位必定為 1,因此可以忽略掉該位,這樣用同樣多的位數就能多存一位二進位制數,有利於提高資料表示精度,稱這種處理方案使用了隱藏位技術。當然,在取回這樣的浮點數到運算器執行運算時,必須先恢復該隱藏位。

(2) 階碼使用「移碼」,基固定為2

如下圖的32bit浮點數和64bit浮點數,從最高位依次是符號位、階碼和尾數

於是,乙個規格化的32位浮點數x的真值為:

\(x = (-1)^s\times(1.m)\times2^\)

乙個規格化的64位浮點數x的真值為:

\(x = (-1)^s\times(1.m)\times2^\)

下面舉乙個32位單精度浮點數-3.75表示的例子幫助理解:

(1)首先轉化為2進製表示

\(-3.75 = -(2+1+1/2+1/4) = -1.111\times2^1\)

(2)整理符號位並進行規格化表示

\(-1.111\times2^1 = (-1)^\times(1+0.1110\ 0000\ 0000\ 0000\ 0000\ 000)\times2^1\)

(3)進行階碼的移碼處理

\((-1)^\times(1+0.1110\ 0000\ 0000\ 0000\ 0000\ 000)\times2^1\)

\(=(-1)^\times(1+0.1110\ 0000\ 0000\ 0000\ 0000\ 000)\times2^\)

於是,符號位s=1,尾數m為\(1110\ 0000\ 0000\ 0000\ 0000\ 000\)階碼e為\(128_=1000\ 0000_2\),則最終的32位單精度浮點數為

\(1\ 1110\ 0000\ 0000\ 0000\ 0000\ 000\ 1000\ 0000\)

通過上面的規格化表示,我們可以很容易確定浮點數的表示範圍:

既然有表示範圍,那肯定也有不能表示的數值:

首先來說明溢位值,如下圖:

(1)無窮值:

如果指數\(e=11111111_2=255_\)且尾數\(m=0\),則根據符號位s分別表示\(+\infty\)和\(-\infty\)。因此,乙個有效的32位浮點數其指數最大只能為254。

此外,無窮具有傳遞性,比如

(+∞) + (+7) = (+∞)

(+∞) × (−2) = (−∞)

(+∞) × 0 = nan

(2)零值:

如果指數\(e=0\)且尾數\(m=0\)時,表示機器0.需要注意的是,這裡的0也是有符號的,在數值比較的時候 \(+0=-0\); 但在一些特殊操作下,二者並不顯相等,比如\(\log(x)\), \(\frac \neq \frac\)。

此外,處於負下溢位和負上溢位之間的數值會被直接歸為0。

(3)nan:

如果\(e=0\)且尾數\(m\neq 0\),則表示這個值不是乙個真正的值(not a number)。nan又分成兩類:qnan(quiet nan)和snan(singaling nan)。qnan與snan的不同之處在於,qnan的尾數部分最高位定義為1,snan最高位定義為0;qnan一般表示未定義的算術運算結果,如\(\frac\), \(\infty \times 0\), \(sqrt(-1)\);snan一般被用於標記未初始化的值,以此來捕獲異常。

一般提到浮點數的精度(有效位數)的時候,總是會出現float的有效位為6~7位, double的有效位為15~16位

下面以float為例,解釋一下有效位數是怎樣來的。

有效位數只和規格化浮點數的尾數部分有關,而尾數部分的位數是23位,因此我們首先列出下表

由上面的**可以看出:

\(2^\) 和 \(2^\) 之間是存在間隔的,即0.0000001和0.0000002之間的小數我們是沒有辦法描述的,因此23位尾數最多只能描述到小數點後第7位;此外,我們通過四捨五入可以很容易發現\(0.0000003 = 0.0000004 = 2^+2^\), 這表明第7位有效數字只是部分準確。而第6位及之前的都是可以準確描述的,因此我們說float的有效位為6~7位。

(1) wiki 詞條 「floating point」:

(2) wiki 詞條 「ieee floating point」:

(2) 浮點異常值:nan,qnan,snan:

IEEE的浮點數表示

ieee浮點標準用v 1 s m 2 e 由符號,尾數,階碼表示 32位單精度 單精度二進位制小數,使用32位儲存。1 8 23 位長 s exp fraction 31 30 23 22 0 位編號 從右邊開始為0 偏正值 127 64位雙精度 雙精度 二進位制小數,使用64位儲存。1 11 52...

C51浮點數顯示 浮點數表示方法

c51中的浮點數儲存方式 n年前曾在c51bbs論壇中發布過 float 浮點形,它是符合ieee 754標準的單精度浮點形資料,在十進位制中具有7位有效數字。float型據占用四個位元組 32位二進位制數 在記憶體中的存放格式如下 位元組位址 由低到高 0 1 2 3 浮點數內容 mmmmmmmm...

析IEEE浮點數表示法

眾所周知,計算機中的所有資料都是以二進位制表示的,浮點數也不例外。然而浮點數的二進位制表示法卻不像定點數那麼簡單了。先澄清乙個概念,浮點數並不一定等於小數,定點數也並不一定就是整數。所謂浮點數就是小數點在邏輯上是不固定的,而定點數只能表示小數點固定的數值,具用浮點數或定點數表示某哪一種數要看使用者賦...