1.實數數的表示
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
