浮點運算:雙精度、單精度、半精度浮點數計算(FP16/FP32/FP64),浮點和定點


1.實數數的表示

參考深入理解C語言-03-有符號數,定點數,浮點數

1.1定點數

一般在沒有FPU寄存器的嵌入式系統中使用比較多。比如常見的32位系統中,將高16位作為整數部分,低16位作為小數部分。
這樣就可以用整數來模擬定點數的 +  - * / 運算。
關於定點數的數學分析,請參考以下文檔:
http://www.digitalsignallabs.com/fp.pdf

代碼實現可以參考以下文檔:
http://www.eetimes.com/author.asp?section_id=36&doc_id=1287491

1.2浮點數

格式:

         s符號位  exp指數   frac尾數   精度說明

16位       1            5             11            半精度 FP16
32位       1            8             23            單精度 FP32
64位       1           11            52            雙精度 FP64
11位       1            4             6              沒找到應用 11bit存儲起來也奇怪

表示的數為: (-1)的s次方 *  2的(exp -base)次方 * (1 + frac)
base = 2的(exp位數 -1) -1 對於32位,為127 = 2的7次方 -1

比如0.325 =1.3 / 4  (規范化,這種方式在信息處理中很常見)
則s為0, exp為 127 + (-2) = 125, frac為0.3
近一步把0.3表示為  1/4 + 1/20 = (1/4) * ( 1 + 1/5)
注意到1/5可以表示為 (3/16) / (1 - 1/16) = (3/16) ( 1 + 1/16 + (1/16)*(1/16) + ... (無窮級數展開)
對應的二進制表示為
0.  01  (0011) (0011) ...
取前23位,則為:
0100110 01100110 01100110

這樣,0.325在內存中的2進制表示為:
0  01111101  0100110 01100110 01100110

對應16進制為:3E A6 66 66

2.精度說明

半精度 16bit,單精度32bit,雙精度64,上文已經提出,需要注意的是FP16,FP32,FP64都有隱藏的起始位。

參考程序員必知之浮點數運算原理詳解

以半精度FP16為例說明

2.1半精度FP16

3.浮點運算加法和乘法

相比於整數加法和乘法多了比較,移位邏輯,比整數復雜很多

3.1加法

       浮點加法器首先對浮點數拆分,得到符號、階碼、尾數。對拆分結果進行絕對值比較,得到大的階碼、階差和比較結果輸出。然后進行對階,通過移位小的尾數,得到相同大階。對尾數進行尾數加減運算,得到的結果進行規格化,最后結合規格化結果運算結果符號輸出,得到結果輸出。

        一.需要注意一個是以絕對值大的對階數(exponent), 二.對結果規格化規划到(1+Frac)的形式。

3.2乘法

       符號位只是兩者的異或,指數位基本上是兩指數的相加,而尾數位就需要在正常的乘法之余考慮到移位(和隨之而來的指數為的溢出)和進位的情況。

原文鏈接:https://blog.csdn.net/cy413026/article/details/101457312


 

浮點數是計算機上最常用的數據類型之一,有些語言甚至數值只有浮點型(Perl,Lua同學別跑,說的就是你)。

常用的浮點數有雙精度和單精度。除此之外,還有一種叫半精度的東東。

雙精度64位,單精度32位,半精度自然是16位了。

半精度是英偉達在2002年搞出來的,雙精度和單精度是為了計算,而半精度更多是為了降低數據傳輸和存儲成本。

很多場景對於精度要求也沒那么高,例如分布式深度學習里面,如果用半精度的話,比起單精度來可以節省一半傳輸成本。考慮到深度學習的模型可能會有幾億個參數,使用半精度傳輸還是非常有價值的。

Google的TensorFlow就是使用了16位的浮點數,不過他們用的不是英偉達提出的那個標准,而是直接把32位的浮點數小數部分截了。據說是為了less computation expensive。。。

比較下幾種浮點數的layout:

雙精度浮點數

 

 

單精度浮點數

 

 

半精度浮點數

 

 

它們都分成3部分,符號位,指數和尾數。不同精度只不過是指數位和尾數位的長度不一樣。

解析一個浮點數就5條規則

如果指數位全零,尾數位是全零,那就表示0
如果指數位全零,尾數位是非零,就表示一個很小的數(subnormal),計算方式 (−1)^signbit × 2^−126 × 0.fractionbits
如果指數位全是1,尾數位是全零,表示正負無窮
如果指數位全是1,尾數位是非零,表示不是一個數NAN
剩下的計算方式為 (−1)^signbit × 2^(exponentbits−127) × 1.fractionbits
常用的語言幾乎都不提供半精度的浮點數,這時候需要我們自己轉化。

具體可以參考Numpy里面的代碼:

https://github.com/numpy/numpy/blob/master/numpy/core/src/npymath/halffloat.c#L466

當然按照TensorFlow那么玩的話就很簡單了(~攤手~)。

參考資料:

https://en.wikipedia.org/wiki/Half-precision_floating-point_format

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

https://en.wikipedia.org/wiki/Single-precision_floating-point_format

http://download.tensorflow.org/paper/whitepaper2015.pdf
————————————————
版權聲明:本文為CSDN博主「AI圖哥」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sinat_24143931/article/details/78557852


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM