浮點數(shù)在計算機中是如何表示的偏形?
學過《計算機組成原理》或者類似《計算機系統(tǒng)》這些課程的小伙伴們應該都知道,浮點數(shù)在計算機中的存儲方式遵循IEEE 754 浮點數(shù)計數(shù)標準纲菌,可以表示為:
采用尾數(shù) + 階碼的編碼方式,更通俗一點說贾陷,就是類似于數(shù)學課本上所學的科學計數(shù)法表示方式:有效數(shù)字 + 指數(shù)位!
因此嘱根,只要給出:符號(S)髓废、階碼部分(E)、尾數(shù)部分(M)這三個維度的信息该抒,一個浮點數(shù)的表示就完全確定下來了慌洪,所以float和double這兩種類型的浮點數(shù)在計算機中的存儲結構就表示成下圖所示這個樣子:
1、符號部分(S)
0-正1-負
2凑保、階碼部分(E)(指數(shù)部分):
對于float型浮點數(shù)冈爹,指數(shù)部分8位,考慮可正可負欧引,因此可以表示的指數(shù)范圍為-127 ~ 128
對于double型浮點數(shù)频伤,指數(shù)部分11位,考慮可正可負芝此,因此可以表示的指數(shù)范圍為-1023 ~ 1024
3憋肖、尾數(shù)部分(M):
浮點數(shù)的精度是由尾數(shù)的位數(shù)來決定的:
對于float型浮點數(shù),尾數(shù)部分23位婚苹,換算成十進制就是2^23=8388608岸更,所以十進制精度只有6 ~ 7位;
對于double型浮點數(shù)膊升,尾數(shù)部分52位怎炊,換算成十進制就是2^52 = 4503599627370496,所以十進制精度只有15 ~ 16位
所以廓译,浮點數(shù)交給計算機存儲的時候结胀,可能會有精度丟失問題!T鹧糟港!因此使用時需要格外小心,如果真因為這一塊出了bug院仿,定位問題還是非常艱難的秸抚,所以預防工作要做好。
進制轉換計算案例
上面說的是IEEE標準規(guī)定的內容歹垫,屬于理論規(guī)約剥汤。那一個小數(shù)到底要怎么換算成二進制呢?我們得拿實際例子來解釋排惨。
先來個簡單的例子
比如:把十進制小數(shù)0.875轉換成二進制吭敢,具體怎么操作?
可以分幾大步走:
1暮芭、以小數(shù)點為界鹿驼,拆分
2欲低、整數(shù)部分轉換
整數(shù)轉二進制我想大家應該都熟悉,使用:除2取余法即可畜晰。而這里的0.875整數(shù)部分為0砾莱,無需操作。
3凄鼻、小數(shù)部分轉換
小數(shù)部分的轉換不同于整數(shù)部分腊瑟,采用的是“乘2取整法”,圖示一下就明白了:
4块蚌、合并結果
整數(shù)部分 + 小數(shù)部分闰非,最終得到二進制結果為0.111。
所以該結果按照上一節(jié)所述的尾數(shù) + 階碼的計算機計數(shù)方式峭范,則可以表示為:
所以對應可得:
符號位:0
階碼(E)部分:若以float為例河胎,應為127 +(-1)= 126,因此二進制表示為:01111110
尾數(shù)部分(M):若以float為例虎敦,應為23位游岳,因此尾部補齊后為11000000000000000000000。
因此最終的總結果為(以32位精度float表示):
00111111011000000000000000000000
再來個復雜點例子
再比如:把十進制小數(shù)6.36轉換成二進制其徙,具體怎么操作胚迫?
但凡能用圖示,我就不想寫文字唾那,所以用一張圖就可以解釋得明明白白:
整數(shù)部分 + 小數(shù)部分访锻,因此最終得到的結果二進制結果為110.01011100...。
還是按照上一節(jié)所述的尾數(shù) + 階碼的計算機計數(shù)方式闹获,則可以表示為:
所以對應可得:
符號位:0
階碼(E)部分:若以float為例期犬,應為127 +(2)= 129,因此二進制表示為:10000001
尾數(shù)部分(M):1001011100...避诽,其實它本身無限不循環(huán)龟虎,但若以float型精度來截取23位,則可以表示為10010111000010100011111
因此最終的總結果為(以32位精度float表示):
01000000110010111000010100011111
所以像這種無限位數(shù)的尾數(shù)情況沙庐,用計算機存儲產生截取是必然的鲤妥,必定會有一定的精度損失!所以這也從根本上解釋了為什么float或者double這種類型數(shù)據(jù)使用時的風險性拱雏,因此必須要結合實際業(yè)務理性考量棉安。
還有一個神器
大家如果對上面的計算結果不放心,或者想檢查手動換算的結果是否正確铸抑,也有直接的這種二進制轉換工具站贡耽,典型的比如:binaryconvert.com
不想手動換算的,直接去上面輸入,轉換一下即可得到結果蒲赂,而且可以進制互換:
參考:CodeSheep