都工做兩年了,還不知道浮點數如何轉二進制?

image


來吧,坐下聊

先前在前文 《老大說:誰要再用double定義商品金額,就本身收拾東西走》 中就已經痛徹心扉地聊過:工具

在處理諸如 訂單交易貨幣計算、以及 商品金額慎用浮點數( double/ float)去定義變量,不然可能會遇到各類奇葩的問題,具體示例在那篇文章中都詳細展現過。

當時寫那篇文章的時候,我覺得你們對於小數轉二進制的換算早已瞭然於胸,因此也就沒有給出具體的換算過程。結果文章發出來後,私信裏一票小夥伴反饋說,文中那些小數轉二進制的例子究竟是怎麼換算出來的,最好詳解一下。編碼

image

得嘞,這不就來了嘛!spa

順帶聊一句,看來《計組原理》或者說《計算機系統》這門課有必要小規模回爐重造一下了(滑稽)。3d

不過實不相瞞,CRUD、複製粘貼、調接口、寫業務代碼久了,計算機基礎確實好多都忘了...我也有深有同感!code


浮點數在計算機中是如何表示的?

學過 《計算機組成原理》 或者相似 《計算機系統》 這些課程的小夥伴們應該都知道,浮點數在計算機中的存儲方式遵循IEEE 754 浮點數計數標準,能夠表示爲:blog

image

採用尾數 + 階碼的編碼方式,更通俗一點說,就是相似於數學課本上所學的科學計數法表示方式:有效數字 + 指數位接口

所以,只要給出:符號(S)階碼部分(E)尾數部分(M) 這三個維度的信息,一個浮點數的表示就徹底肯定下來了,因此floatdouble這兩種類型的浮點數在計算機中的存儲結構就表示成下圖所示這個樣子:rem

image

image

一、符號部分(S)數學

0-正 1-負it

二、階碼部分(E)(指數部分)

  • 對於float型浮點數,指數部分8位,考慮可正可負,所以能夠表示的指數範圍爲-127 ~ 128
  • 對於double型浮點數,指數部分11位,考慮可正可負,所以能夠表示的指數範圍爲-1023 ~ 1024

三、尾數部分(M)

浮點數的精度是由尾數的位數來決定的:

  • 對於float型浮點數,尾數部分23位,換算成十進制就是 2^23=8388608,因此十進制精度只有6 ~ 7位;
  • 對於double型浮點數,尾數部分52位,換算成十進制就是 2^52 = 4503599627370496,因此十進制精度只有15 ~ 16

因此,浮點數交給計算機存儲的時候,可能會有精度丟失問題!!!所以使用時須要格外當心,若是真由於這一塊出了bug,定位問題仍是很是艱難的,因此預防工做要作好。


進制轉換計算案例

上面說的是IEEE標準規定的內容,屬於理論規約。那一個小數到底要怎麼換算成二進制呢?咱們得拿實際例子來解釋。

先來個簡單的例子

好比:把十進制小數0.875轉換成二進制,具體怎麼操做?

能夠分幾大步走:

一、以小數點爲界,拆分

二、整數部分轉換

整數轉二進制我想你們應該都熟悉,使用:除2取餘法 便可。而這裏的0.875整數部分爲0,無需操做。

三、小數部分轉換

小數部分的轉換不一樣於整數部分,採用的是 「乘2取整法」 ,圖示一下就明白了:

image

四、合併結果

整數部分 + 小數部分,最終獲得二進制結果爲0.111

因此該結果按照上一節所述的尾數 + 階碼的計算機計數方式,則能夠表示爲:

image

因此對應可得:

  • 符號位0
  • 階碼(E)部分:若以float爲例,應爲 127 +(-1)= 126,所以二進制表示爲:01111110
  • 尾數部分(M):若以float爲例,應爲23位,所以尾部補齊後爲11000000000000000000000

所以最終的總結果爲(以32位精度float表示):

00111111011000000000000000000000

再來個複雜點例子

再好比:把十進制小數6.36轉換成二進制,具體怎麼操做?

但凡能用圖示,我就不想寫文字,因此用一張圖就能夠解釋得明明白白:

image

整數部分 + 小數部分,所以最終獲得的結果二進制結果爲110.01011100...

仍是按照上一節所述的尾數 + 階碼的計算機計數方式,則能夠表示爲:

image

因此對應可得:

  • 符號位:0
  • 階碼(E)部分:若以float爲例,應爲 127 +(2)= 129,所以二進制表示爲:10000001
  • 尾數部分(M)1001011100...,其實它自己無限不循環,但若以float型精度來截取23位,則能夠表示爲10010111000010100011111

所以最終的總結果爲(以32位精度float表示):

01000000110010111000010100011111

因此像這種無限位數的尾數狀況,用計算機存儲產生截取是必然的,一定會有必定的精度損失!因此這也從根本上解釋了爲何float或者double這種類型數據使用時的風險性,所以必需要結合實際業務理性考量。


神器加持

你們若是對上面的計算結果不放心,或者想檢查手動換算的結果是否正確,也有直接的這種二進制轉換工具站,典型的好比binaryconvert

image

不想手動換算的,直接去上面輸入,轉換一下便可獲得結果,並且能夠進制互換,使用很是方便。


回味

有時候回顧一下基礎真的蠻有意思的,好比寫這篇文章時,雖然是很基礎的東西,可是表達出來的過程仍是挺有趣的,尤爲是畫圖展示的過程,但願能和小夥伴們共勉。

相關文章
相關標籤/搜索