1. 程式人生 > >[算法]浮點數在內存中的存儲方式

[算法]浮點數在內存中的存儲方式

www. sig 後者 mage 工具 32bit alt iss bits

float型變量占用32bit,即4個byte的內存空間

我們先來看下浮點數二進制表達的三個組成部分。

技術分享圖片

三個主要成分是:

  • Sign(1bit):表示浮點數是正數還是負數。0表示正數,1表示負數
  • Exponent(8bits):指數部分。類似於科學技術法中的M*10^N中的N,只不過這裏是以2為底數而不是10。需要註意的是,這部分中是以2^7-1即127,也即01111111代表2^0,轉換時需要根據127作偏移調整。
  • Mantissa(23bits):基數部分。浮點數具體數值的實際表示。

下面我們來看個實際例子來解釋下轉換過程。
Step 1 改寫整數部分
以數值5.2為例。先不考慮指數部分,我們先單純的將十進制數改寫成二進制。
整數部分很簡單,5.即101.。

Step 2 改寫小數部分
小數部分我們相當於拆成是2^-1一直到2^-N的和。例如:
0.2 = 0.125+0.0625+0.007825+0.00390625即2^-3+2^-4+2^-7+2^-8….,也即.00110011001100110011。

或者換個更傻瓜的方式去解讀十進制對二進制小數的改寫轉換,通常十進制的0.5也(也就是分數1/2),相當於二進制的0.1(同等於分數1/2),

我們可以把十進制的小數部分乘以2,取整數部分作為二進制的一位,剩余小數繼續乘以2,直至不存在剩余小數為止。

例如0.2可以轉換為:

0.2 x 2 = 0.4 0

0.4 x 2 = 0.8 0

0.8 x 2 = 1.6 1

0.6 x 2 = 1.2 1

0.2 x 2 = 0.4 0

0.4 x 2 = 0.8 0

0.8 x 2 = 1.6 1

.......

即:.0011001.......(它是一個無限循環的二進制數,明白為什麽十進制小數轉換成二進制小數的時候為什麽會出現精度損失的情況了嗎)

Step 3 規格化
現在我們已經有了這麽一串二進制101.00110011001100110011。然後我們要將它規格化,也叫Normalize。其實原理很簡單就是保證小數點前只有一個bit。於是我們就得到了以下表示:1.0100110011001100110011 * 2^2。到此為止我們已經把改寫工作完成,接下來就是要把bit填充到三個組成部分中去了。

Step 4 填充
指數部分(Exponent):之前說過需要以127作為偏移量調整。因此2的2次方,指數部分偏移成2+127即129,表示成10000001填入。
整數部分(Mantissa):除了簡單的填入外,需要特別解釋的地方是1.010011中的整數部分1在填充時被舍去了。因為規格化後的數值整部部分總是為1。那大家可能有疑問了,省略整數部分後豈不是1.010011和0.010011就混淆了麽?其實並不會,如果你仔細看下後者:會發現他並不是一個規格化的二進制,可以改寫成1.0011 * 2^-2。所以省略小數點前的一個bit不會造成任何兩個浮點數的混淆。
具體填充後的結果見下圖

技術分享圖片

練習:如果想考驗自己是否充分理解這節內容的話,可以隨便寫一個浮點數嘗試轉換。通過 浮點二進制轉換工具可以驗證答案。

[算法]浮點數在內存中的存儲方式