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