IEEE 754格式是什麼?

計算機編程語言中里有提到浮點類型float和double採用了IEEE754格式


在這裡詳細介紹下,也當作自己的總結:

首先介紹一些基本數據類型的數值範圍以及注意事項:

4位元組有符號int值:-2^31 至 2^31-1 (由於計算機採用補碼標示,+0代表0 -0代表絕對值最大的負值)是21億多的範圍具體就是 -21 4748 3648 到 21 4748 3647

附帶提一句: 在Java代碼中調用System.out.println(System.currentTimeMillis()); 返回的數值現在是

14424 1484 5783 這是ms的標示值,一般情況下我們那顯示都是精確到s,那麼(int)(time/1000就可以了,注意,此時的值是14億多,這樣其實離int的最大值還有相當距離,如果我們默認自己的應用不會再30年之後使用,大可使用int,但是建議使用long。

插個有趣的事情,維基百科上關於Unix時間的條目

2038年問題

主條目:2038年問題

2038年1月19日3時14分07秒,32位系統的UNIX時間將會被重置。

現時大部分使用UNIX的系統都是32位的,即它們會以32位有符號整數表示時間類型time_t。因此它可以表示136年的秒數。表示協調世界時間1901年12月13星期五20時45分52秒至2038年1月19日3時14分07秒(二進位:01111111 11111111 11111111 11111111,0x7FFF:FFFF),在下一秒二進位數字會是10000000 00000000 00000000 00000000(0x8000:0000),這是負數,因此各系統會把時間誤解作1901年12月13日20時45分52秒(亦有說回歸到1970年)。這時可能會令軟體發生問題,導致系統癱瘓。

目前的解決方案是把系統由32位轉為64位系統。在64位系統下,此時間最多可以表示到292,277,026,596年12月4日15時30分08秒。

Unix負時間導致部分iPhone手機無法啟動

在2016年2月12日,據披露,如果把蘋果iPhone、iPad等設備的系統時間設置為1970年1月1日,隨後重啟設備,它會直接變磚。目前蘋果公司正式承認了漏洞存在,但是尚未公布具體的引發原因。

[2]

部分中國大陸用戶猜想這是因為調整當地時間到1970.1.1 0:00後,如果時區為正,那麼GMT時間就早於unix定義的0時間。例如北京時間 1970.1.1 0:00 (UTC+0800) 是UTC 1969.12.31 16:00 對應的unix時間是負的。但是有人回應嘗試設為正時區重啟後仍然變磚。

[3]

蘋果對此採用的策略是在隨後的固件更新中將時間禁止調整到2000年以前。2位元組short值: -2^15 到 2^15-1 這也恰巧和計算機埠號的範圍類似 0-65535(

系統保留埠(從0到1023) 動態埠(從1024到65535) )

1位元組byte值:-2^7 到 2^7-1

那麼4位元組的浮點數的範圍怎麼進行計算?為什麼4位元組的浮點數可以表示那麼大的數據?

下圖是4位元組浮點數在計算機的表示說明:

關於階碼:

在機器中表示一個浮點數時需要給出指數,這個指數用整數形式表示,這個整數叫做階碼,階碼指明了小數點在數據中的位置。

對於任意一個二進位數N,可用N=S×2^P表示,其中S為尾數,P為階碼,2為階碼的底,P、S都用二進位數表示,S表示N的全部有效數字,P指明小數點的位置。當階碼為固定值時,數的這種表示法稱為定點表示,這樣的數稱為「定點數」;當階碼為可變時,數的這種表示法稱為浮點表示,這樣的數稱為「浮點數」。

為什麼要定義使用階碼? 因為浮點數的定義導致的,也是浮點數的表示需求產生的。

浮點數是屬於有理數中某特定子集的數的數字表示,在計算機中用以近似表示任意某個實數。具體的說,這個實數由一個整數或定點數(即尾數)乘以某個基數(計算機中通常是2)的整數次冪得到,這種表示方法類似於基數為10的科學記數法。

問題一:為什麼32位浮點數階碼要有偏移量?

原因還是為了計算機處理數據的方便,還記得為什麼計算機要有補碼嗎?原因就是希望在加法運算中將減法運算一併處理了,簡化CPU中運算器的設計,確實我們通過補碼實現了加減法的統一。

現在我們將浮點數用這種形式保存,那麼計算機怎麼比較浮點數的大小呢?

浮點數表示有兩個符號位置,一個是數符S,一個是階碼的符號,如果僅僅採用補碼作為階碼,於階碼有正有負,整個數的符號位和階數的符號位將導致不能進行簡單的大小比較,所以階數採用了一個無符號的正整數存儲。階數的值直接進行二進位計算,符號位置是默認為0的,於是階數的值可以為0 到 255

問題二:為什麼偏移量設置為127?

當階碼E 為全0且尾數M 也為全0時,表示的真值x 為零,結合符號位S 為0或1,有正零和負

零之分。當階碼E 為全1且尾數M 為全0時,表示的真值x 為無窮大,結合符號位S
為0或1,也有

+∞和-∞之分。這樣在32位浮點數表示中,要除去E 用全0和全1(255)10表示零和無窮大的特殊

情況,指數的偏移值不選128(10000000),而選127(01111111)。對於規格化浮點數,E 的範圍變

為1到254,真正的指數值e
則為-126到+127。因此32位浮點數表示的絕對值的範圍是10-38~10^38

(以10的冪表示)。

這樣我們就知道了,其實我們的浮點數是這樣表示在計算機噹噹中的,那麼浮點數的範圍呢?

float與double的範圍和精度

1. 範圍

float和double的範圍是由指數的位數來決定的。

float的指數位有8位,而double的指數位有11位,分布如下:

float:

1bit(符號位) 8bits(指數位) 23bits(尾數位)

double:

1bit(符號位) 11bits(指數位) 52bits(尾數位)

於是,float的指數範圍為-126~+127,而double的指數範圍為-1022~+1023,並且指數位是按補碼的形式來劃分的。

之所以是上面的範圍:上面黑體字部分已經解釋了,為了比較方便,我們將指數加偏移量改為正值,由於隱匿一位偏移導致偏移量整體-1

其中負指數決定了浮點數所能表達的絕對值最小的非零數;而正指數決定了浮點數所能表達的絕對值最大的數,也即決定了浮點數的取值範圍。

float的範圍為-2^127 ~ +2^127,也即-3.40E+38 ~ +3.40E+38;double的範圍為-2^1023 ~ +2^1023,也即-1.79E+308 ~ +1.79E+308。

2. 精度

float和double的精度是由尾數的位數來決定的。浮點數在內存中是按科學計數法來存儲的,其整數部分始終是一個隱含著的「1」,由於它是不變的,故不能對精度造成影響。

float:2^23 = 8388608,一共七位,這意味著最多能有7位有效數字,但絕對能保證的為6位,也即float的精度為6~7位有效數字;

double:2^52 = 4503599627370496,一共16位,同理,double的精度為15~16位。

這樣IEE754就算基本弄清了吧

參考這個資料可以獲得更詳細的解釋

計算機中常用的數據表示格式有兩種,一是定點格式,二是浮點格式。一般來說,定點格式容

許的數值範圍有限,但要求的處理硬體比較簡單。而浮點格式容許的數值範圍很大,但要求的處

理硬體比較複雜。

定點表示:約定機器中所有數據的小數點位置是固定不變的。由於約定在固定的位置,小數

點就不再使用記號「.」來表示。通常將數據表示成純小數純整數

  定點數x=x012…xn 在定點機中表示如下(0:符號位,0代表正號,1代表負號):

純小數的表示範圍為(012…xn 各位均為0時最小;各位均為1時最大)

純整數的表示範圍為

目前計算機中多採用定點純整數表示,因此將定點數表示的運算簡稱為整數運算

電子的質量(9×10-28克)和太陽的質量(2×1033克)相差甚遠,在定點計算機中無法直接來表

示這個數值範圍.要使它們送入定點計算機進行某種運算,必須對它們分別取不同的比例因子,

使其數值部分絕對值小於1,即:

這裡的比例因子10-27和 1034要分別存放在機器的某個存儲單元中,以便以後對計算結果

按這個比例增大。顯然這要佔用一定的存儲空間和運算時間。因此得到浮點表示法如下:

  浮點表示法:把一個數的有效數字和數的範圍在計算機的一個存儲單元中分別予以表示,

這種把數的範圍和精度分別表示的方法,數的小數點位置隨比例因子的不同而在一定範圍內自

由浮動。

  任意一個十進位數 可以寫成

為提高數據的表示精度,當尾數的值不為 0 時,尾數域的最高有效位應為1,否則以修改

階碼同時左右移小數點的辦法,使其變成這一表示形式,這稱為浮點數的規格化表示

  當浮點數的尾數為 0,不論其階碼為何值,或者當階碼的值遇到比它能表示的最小值還小

時,不管其尾數為何值,計算機都把該浮點數看成零值,稱為機器零

  當階碼E 為全0且尾數M 也為全0時,表示的真值x 為零,結合符號位S
為0或1,有正零和負

零之分。當階碼E 為全1且尾數M 為全0時,表示的真值x 為無窮大,結合符號位S
為0或1,也有

+∞和-∞之分。這樣在32位浮點數表示中,要除去E 用全0和全1(255)10表示零和無窮大的特殊

情況,指數的偏移值不選128(10000000),而選127(01111111)。對於規格化浮點數,E 的範圍變

為1到254,真正的指數值e
則為-126到+127。因此32位浮點數表示的絕對值的範圍是10-38~1038

(以10的冪表示)。

浮點數所表示的範圍遠比定點數大。一台計算機中究竟採用定點表示還是浮點表示,

要根據計算機的使用條件來確定。一般在高檔微機以上的計算機中同時採用定點、浮點

表示,由使用者進行選擇,而單片機中多採用定點表示。


就是由電氣電子工程師學會定義的浮點數在內存中的演算法規範。


IEEE 754: Standard for Binary Floating-Point Arithmetic

IEEE754標準 單精度(32位)/雙精度(64位)浮點數解碼


推薦閱讀:

Android開發和前端開發,該選擇哪個?
Minecraft開發圈內應不應該開發出降低門檻的程序?
C++求余用的「%」有與它效率相同的其它演算法嗎?
C語言中,main為什麼可以不是函數?
有沒有中英文均有,且有字重和斜體的等寬字體?

TAG:程序員 | 編程語言 | 編程 | 浮點數 | IEEE754 |