float型和double型數據的存儲方式(學習記錄)

對於浮點類型的數據採用單精度類型(float)和雙精度類 型(double)來存儲,float數據佔用32bit,double數據佔用64bit。

通常float可以保證十進制科學計數法小數點後6位有效精度和第7位的部分精度

double可以保證十進制科學計數法小數點後15位有效精度和第16位的部分精度。

因爲float和double的精度是由尾數決定的,什麼是尾數呢,下面看看浮點型數據在底層是如何存儲的。

我們在聲明一個變量float f= 2.25f的時候,是如何分配內存的呢?如果胡亂分配,那世界豈不是亂套了麼?

其實不論是float還是double在存儲方式上都是遵從IEEE的規範 的,float遵從的是IEEE R32.24 ,而double 遵從的是R64.53

無論是單精度還是雙精度在存儲中都分爲三個部分:
符號位(Sign) : 0代表正,1代表爲負
指數位(Exponent):用於存儲科學計數法中的指數數據,並且要加上偏移量(float偏移127,double偏移量1023)
尾數部分(Mantissa):尾數部分

其單精度float的存儲方式如下圖所示:
在這裏插入圖片描述
雙精度double的存儲方式爲:
在這裏插入圖片描述
R32.24和R64.53的存儲方式都是用科學計數法來存儲數據的,比如8.25用十進制的科學計數法表示就爲:8.2510的0次方,而120.5可以表示爲:1.20510的2次方

可是計算機根本不認識十進制的數據,只認識0,1,所以在計算機存儲中,首先要將上面的數更改爲二進制的科學計數法表示,8.25用二進制表示可表示爲1000.01,120.5用二進制表示爲:1110110.1。用二進制的科學計數法表示1000.01可以表示爲1.0000123,1110110.1可以表示爲1.110110126。任何一個數都的科學計數法表示都爲1.XXX2n。尾數部分就可以表示爲xxxx,第一位都是1嘛,幹嘛還要表示呀?可以將小數點前面的1省略,所以23bit的尾數部分,可以表示的精度卻變成了 24bit。
在這裏插入圖片描述
在這裏插入圖片描述
奇怪輸出結果:
在這裏插入圖片描述
首先我們看看2.25的單精度存儲方式,2.25 --> 10.01 --> 1.001
21
符號位0,指數部分1+127 --> 10000000
尾數部分:001 0000 0000 0000 0000 0000
很簡單 0 1000 0000 001 0000 0000 0000 0000 0000,
而2.25的雙精度表示爲:0 100 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000,這樣2.25在進行強制轉換的時候,數值是不會變的

而我們再看看2.2呢
發現小數部分的二進制是一個無限循環的排列 00110011001100110011…
對於單精度數據來說,尾數只能表示23bit的精度,所以2.2的float存儲爲:
2.2 --> 10.0011001100110011001100 -->1.00011001100110011001100*21
符號位0,指數部分1+127 --> 1000 0000
尾數部分:00011001100110011001100
0 1000 0000 00011001100110011001100
但是這樣存儲方式,換算成十進制的值,卻不會是2.2的

因爲十進制在轉換爲二進制的時候可能會不準確,如2.2,而double類型的數據也存在同樣的問題,所以在浮點數表示中會產生些許的誤差,在單精度轉換爲雙精度的時候,也會存在誤差的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章