C++浮點型的存儲方式詳解
浮點型及其存儲方式
有些時候需要變量能存儲帶小數(shù)點的數(shù),或者能存儲極大數(shù)或極小數(shù)。這類數(shù)可以用浮點(因小數(shù)點是“浮動的”而得名)格式進行存儲。C語言提供了3種浮點類型,對應三種不同的浮點格式。
當精度要求不嚴格時(小數(shù)點后少于六位),float類型是很適合的類型。double提供更高的精度, 對絕大多數(shù)程序來說夠用了。longdouble支持極高精度的要求,很少會用到。
C標準沒有說明float、double和long double類型提供的的精度到底是多少,因為不同計算機可以用不同方法存儲浮點數(shù)。大多數(shù)現(xiàn)代計算機遵循IEEE754標準(即IEC 60559) 的規(guī)范,所以這里也將它作為一個示例。
一、IEEE浮點標準
由IEEE開發(fā)的IEEE標準提供了兩種主要的浮點數(shù)格式:單精度(32位) 和雙精度(64位)。數(shù)值以科學記數(shù)法的形式存儲,每一個數(shù)都由三部分組成:符號、指數(shù)和小數(shù)。指數(shù)部分的位數(shù)說明了數(shù)值的可能大小程度,而小數(shù)部分的位數(shù)說明了精度。單精度格式中,指數(shù)長度為8位,而小數(shù)部分占了23位。因此,單精度數(shù)可以表示的最大值大約是3.40×1038,其中精度是6個十進制數(shù)字。
IEEE標準還描述了另外兩種格式:單擴展精度和雙擴展精度。標準沒有指明這些格式中的位數(shù),但要求單擴展精度類型至少為43位,而雙擴展精度類型至少為79位。
類型 | 最小值 | 最大值 | 精度 | 備注 |
---|---|---|---|---|
●float | 1.175 49×10-38 | 3.402 82×1038 | 小數(shù)點后6位 | 單精度32位 |
●double | 2.225 07×10-308 | 1.797 69×10308 | 小數(shù)點后15位 | 雙精度64位 |
上表給出了根據(jù)IEEE標準實現(xiàn)的浮點類型特征。[表中給出了規(guī)范化的最小正值, 非規(guī)范化的數(shù)可以更小。] long double類型沒有顯示在此表中, 因為它的長度隨著機器的不同而變化,而最常見的大小是80位和128位。
二、存儲方式
對于浮點型數(shù)據(jù),首先我們需要明白的一點是:浮點數(shù)和整型數(shù)的編碼方式是不一樣的,IEEE浮點標準采用如下形式來標識一個浮點數(shù)。
V = (-1)S M 2E
- (-1)S 表示符號位,當S=0時,表示正數(shù),當S=1時,表示負數(shù)。
- M 表示有效數(shù)字,是一個二進制小數(shù),其值大于等于1,小于2。
- 2E 表示指數(shù)位。
下面,我將用float作為例子,double道理也是一樣的,只是位數(shù)有所不同。
例如:十進制數(shù):88.8125 —> 二進制為:101 1000.1101
然后將101 1000.1101化成上述公式M的形式,其范圍是[1,2),所以將小數(shù)點左移6位,得到1.0110001101×26(這里不懂的話對比十進制,小數(shù)點左移一位乘以10,二進制則乘以2)。
最后得到S = 0、M = 1.0110001101、E = 6,但是事情并沒有那么簡單,我們接著往下看。
IEEE 754對有效數(shù)字M和指數(shù)E的規(guī)定。
1、有效數(shù)字M:
1<=M<2,也就是說,M寫成1.xxx……的形式,其中xxx……表示小數(shù)部分。
IEEE 754規(guī)定,在計算機內(nèi)部保存M時,默認這個數(shù)的第一位總是1,因此可以被舍去,只保存小數(shù)部分。比如保存1.0110001101時,只保存0110001101,后面的位數(shù)補0就可以了,等到讀取的時候,再把第一位的1補上去。
2、指數(shù)E:
首先,E為一個無符號整數(shù)(unsigned int)
如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。但是,我們知道,科學計數(shù)法是可以出現(xiàn)負數(shù)的,所以IEEE 754規(guī)定,存入內(nèi)存的E是真實值加上一個中間數(shù),對于8位的E,中間數(shù)是127,對于11位的E,中間數(shù)是1023。比如,26 的E是6,所以保存為32位浮點數(shù)時,必須保存為6+127=133,即10000101。
重點:
結(jié)合上述補充的信息完善例子
float:
十進制數(shù):88.8125 二進制為:101 1000.1101 == 1.0110001101×26
- 符號位:0
- 指數(shù)位:6+127=133 二進制為:1000 0101
- 小數(shù)位:1.0110001101去掉最高位1則為:0110001101
因此浮點數(shù)88.8125的IEEE浮點表示為:
----0----1000 0101----011 0001 1010 0000 0000 0000
符號位- -指數(shù)域- - - - - - - - - - -小數(shù)域
根據(jù)指數(shù)域不同取值分為一下三種情況:
1)E不全為0或不全為1(規(guī)格化值)
這是最常見情況,取出內(nèi)存中的數(shù)時,指數(shù)E的計算值減去127(或1023),得到真實值,再將有效數(shù)字M前加上第一位的1。
2)E全為0(非規(guī)格化值)
這時,浮點數(shù)的指數(shù)E等于1-127(或1-1023)即為真實值,有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxxx的小數(shù)。這樣做是為了表示正負零,以及接近于0的很小的數(shù)字。
舉個例子:編碼為如下情形:
0 0000 0000 000 0000 0000 0000 0000 0001
即2(-23)×2(-126)=2(-149),轉(zhuǎn)成10進制大約等于1.4×10(-45),這就是單精度所能表達最小的正數(shù)了。
3)E全為1(特殊數(shù)值)
當指數(shù)域全為1時屬于這種情形。此時,如果小數(shù)域全為0且符號域S=0,則表示正無窮,如果小數(shù)域全為0且符號域S=1,則表示負無窮。如果小數(shù)域不全為0時,浮點數(shù)將被解釋為NaN, 即不是一個數(shù)(Not a Number) 。比如計算負數(shù)平方根或處理未初始化數(shù)據(jù)時。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
c語言求出給定范圍內(nèi)的所有質(zhì)數(shù)
本文主要介紹了c語言求出給定范圍內(nèi)的所有質(zhì)數(shù)的小程序。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)詳解
這篇文章主要為大家介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12