国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

C++中的浮點(diǎn)數(shù)在機(jī)器中的存儲(chǔ)精度問(wèn)題

2020-11-20 02:12智愛(ài)娟劉雅琴侯鳳云
寫(xiě)真地理 2020年37期
關(guān)鍵詞:浮點(diǎn)數(shù)存儲(chǔ)精度

智愛(ài)娟 劉雅琴 侯鳳云

摘 要: 浮點(diǎn)數(shù)是C++中最基本的數(shù)據(jù)類型,本文討論了浮點(diǎn)數(shù)在機(jī)器內(nèi)存中的存儲(chǔ)情況、浮點(diǎn)數(shù)的顯示以及C++語(yǔ)言編程中使用浮點(diǎn)數(shù)需要注意的幾個(gè)問(wèn)題。

關(guān)鍵詞: C++;浮點(diǎn)數(shù);存儲(chǔ);顯示;精度

【中圖分類號(hào)】TP31 ? ? 【文獻(xiàn)標(biāo)識(shí)碼】A ? ? 【DOI】10.12215/j.issn.1674-3733.2020.37.135

1 引言

C++語(yǔ)言中的浮點(diǎn)數(shù)有float、double和long double三種類型,在使用C++語(yǔ)言編寫(xiě)程序的過(guò)程中,使用最多的是float和double類型的浮點(diǎn)數(shù)。本文以float和double類型的浮點(diǎn)數(shù)為例,說(shuō)明浮點(diǎn)數(shù)在機(jī)器內(nèi)存中的存儲(chǔ)精度以及在C++語(yǔ)言編程中使用浮點(diǎn)數(shù)時(shí)需要注意的幾個(gè)問(wèn)題。

2 浮點(diǎn)數(shù)在機(jī)器內(nèi)存中的存儲(chǔ)

C++語(yǔ)言中的float和double類型的浮點(diǎn)數(shù)在機(jī)器內(nèi)存中存儲(chǔ)時(shí)分別按照IEEE754標(biāo)準(zhǔn)中的單精度浮點(diǎn)格式和雙精度浮點(diǎn)格式進(jìn)行的,而long double類型的浮點(diǎn)數(shù)在機(jī)器中存儲(chǔ)時(shí)的格式和長(zhǎng)度則與機(jī)器所采用的微處理器類型有關(guān)。比如,在IA-32和X86-64系統(tǒng)中l(wèi)ong double是按照IEEE754標(biāo)準(zhǔn)中的80位擴(kuò)展雙精度格式進(jìn)行存儲(chǔ)的。

IEEE754標(biāo)準(zhǔn)規(guī)定,單精度浮點(diǎn)數(shù)在機(jī)器中采用32位二進(jìn)制表示,其中1位符號(hào)位,8位階碼,23位尾數(shù),階碼采用移碼表示(偏置常數(shù)位127),尾數(shù)采用原碼表示(規(guī)格化形式,數(shù)值最高位的“1”隱含,不表示);雙精度浮點(diǎn)數(shù)在機(jī)器中采用64位表示,其中1位符號(hào)位,11位階碼,52位尾數(shù),階碼采用移碼表示(偏置常數(shù)位1023),尾數(shù)采用原碼表示(規(guī)格化形式,數(shù)值最高位的“1”隱含,不表示)。

任意浮點(diǎn)數(shù)N均可表示成規(guī)格化形式為:±1.M×2e,對(duì)應(yīng)IEEE754格式如下(小數(shù)點(diǎn)前總是“1”,故可隱含表示):

如果浮點(diǎn)數(shù)N為正數(shù),則符號(hào)位S為0;N為負(fù)數(shù),則符號(hào)位S=1。單精度浮點(diǎn)格式中,階碼E=e+127;雙精度浮點(diǎn)格式中,階碼E=e+1023。

例如,將十進(jìn)制數(shù)1234567890分別賦值給float型變量a和double型變量b,變量a和b的機(jī)器數(shù)分別是多少呢?

十進(jìn)制數(shù)1234567890轉(zhuǎn)換為二進(jìn)制為:10010011001

01100000001011010010B=1.0010011001011000000010110

10010*230

因?yàn)槭钦龜?shù),S=0;指數(shù)e=30。

對(duì)于變量a,階碼E=e+127=30+127=157=10011101B;M取小數(shù)點(diǎn)后23位,第24位采用“0舍1入”進(jìn)行舍入處理,M=001 0011 0010 1100 0000 0110。變量a的機(jī)器數(shù)是:0100 1110 1001 0011 0010 1100 0000 0110,用十六進(jìn)制表示為:4E932C06。

對(duì)于變量b,階碼E=e+1023=30+1023=1053=10000011101B;M取52位,M=0010 0110 0101 1000 0000 1010 0000 0000 0000 0000 0000 0000 0000。變量b的機(jī)器數(shù)是:0100 0001 1101 0010 0110 0101 1000 0000 1010 0000 0000 0000 0000 0000 0000 0000,用十六進(jìn)制表示為:41D26580A0000000。

3 浮點(diǎn)數(shù)的顯示

由于IEEE754單精度浮點(diǎn)數(shù)的尾數(shù)M為23位二進(jìn)制表示,雙精度浮點(diǎn)數(shù)的尾數(shù)為52位二進(jìn)制表示,再加上1位隱含位“1”,因此單精度浮點(diǎn)數(shù)的都有效二進(jìn)制位為24位,雙精度為53位。而107<224<108,1017<253<1018,故float型浮點(diǎn)數(shù)在機(jī)器上顯示時(shí)最多可顯示8位有效數(shù)字,其中7位為精確值,double型浮點(diǎn)數(shù)則能顯示18位有效數(shù)字,其中17位為精確值。IEEE754浮點(diǎn)數(shù)可以用下式轉(zhuǎn)換為二進(jìn)制數(shù):(-1)S*1.M*2e。

例如,將變量a的機(jī)器數(shù)4E932C06H轉(zhuǎn)換為二進(jìn)制為:(-1)0*1.001 0011 0010 1100 0000 0110*230=1001001100

101100000001100000000,即十進(jìn)制的1234567936,這個(gè)值比實(shí)際值大46。但是,采用同樣的方法將變量b的機(jī)器數(shù)41D26580A0000000H轉(zhuǎn)換為十進(jìn)制為1234567890,結(jié)果和實(shí)際值相同。由此可見(jiàn),double型浮點(diǎn)數(shù)的精度比f(wàn)loat型浮點(diǎn)數(shù)的精度高。

4 在C++語(yǔ)言中使用浮點(diǎn)數(shù)應(yīng)該注意的幾個(gè)問(wèn)題

(1)設(shè)計(jì)浮點(diǎn)數(shù)類型的目的是為了實(shí)現(xiàn)工程計(jì)算和科學(xué)計(jì)算,在工程計(jì)算和科學(xué)計(jì)算中往往沒(méi)有完全精確的計(jì)算結(jié)果,需要的是近似值。因此,在要求精確計(jì)算結(jié)果的場(chǎng)合(尤其是應(yīng)用程序中),比如,對(duì)貨幣計(jì)算時(shí)一般不要使用浮點(diǎn)型數(shù)據(jù),否則,將會(huì)得到錯(cuò)誤的結(jié)果。

例如:假設(shè)想用十元錢(qián)去買(mǎi)價(jià)格不等的游戲幣,游戲幣的標(biāo)價(jià)分別是1元、2元、3元,一直到10元不等。購(gòu)買(mǎi)時(shí),打算從標(biāo)價(jià)為1元游戲幣開(kāi)始按照價(jià)格從低到高的順序依次購(gòu)買(mǎi),每種購(gòu)買(mǎi)一個(gè),直到所剩的錢(qián)不夠支付任何一種游戲幣為止,最后,共可以購(gòu)買(mǎi)多少個(gè)游戲幣呢?還會(huì)剩余多少零錢(qián)呢?

采用浮點(diǎn)數(shù)表示錢(qián)數(shù)和游戲幣的價(jià)格,用C++語(yǔ)言編寫(xiě)程序如下:

#include

#include

using namespace std;

int main( )

{

int itemsBought = 0;//購(gòu)買(mǎi)游戲幣個(gè)數(shù)

double Price;//游戲幣價(jià)格

double Funds = 10.00;//總錢(qián)數(shù)

for (Price =1.00; Funds >= Price; Price +=10.00)

{

Funds -= Price;

itemsBought++;

}

cout< ? ? cout<<"剩余錢(qián)數(shù): "< ? ? }

編譯運(yùn)行程序,得到結(jié)果為:“3個(gè)游戲幣”,“剩余錢(qián)數(shù):4.00元”。很明顯,程序運(yùn)行得到的結(jié)果是錯(cuò)誤的。

解決這個(gè)問(wèn)題的正確辦法是:在編寫(xiě)C++程序時(shí),浮點(diǎn)數(shù)表示錢(qián)數(shù)和游戲幣的價(jià)格。

使用int類型代替double類型修改上面的程序如下:

#include

using namespace std;

int main( )

{

int itemsBought = 0;//購(gòu)買(mǎi)游戲幣個(gè)數(shù)

int Price;//游戲幣價(jià)格

int Funds = 100;//總錢(qián)數(shù)

for (Price = 10; Funds >= Price; Price += 10)

{

Funds -= Price;

itemsBought++;

}

cout< ? ? cout<<"剩余錢(qián)數(shù):"< ? ? }

重新編譯運(yùn)行程序,輸出結(jié)果:“4個(gè)游戲幣”和“剩余錢(qián)數(shù):0元”。顯然,程序執(zhí)行結(jié)果正確。

(2)在程序中不要用浮點(diǎn)型數(shù)據(jù)作為循環(huán)變量

例如,編寫(xiě)程序:從0開(kāi)始按照逐次遞增0.2輸出一直到10。在程序中用float型作為循環(huán)變量,用C++編程如下:

#include

using namespace std;

main(int argc,char *argv)

{

float i;

for(i=0;i<10;i+=.2)

printf("%10f",i);

return 0;

}

編譯運(yùn)行程序,得到的輸出結(jié)果如下:

顯然,程序輸出結(jié)果是錯(cuò)誤的。

解決問(wèn)題的方法是:先將數(shù)據(jù)起始值、終止值和遞增量都擴(kuò)大10倍變成整數(shù),輸出前將結(jié)果再縮小10倍。重新編寫(xiě)程序如下:

#include

using namespace std;

main(int argc,char *argv)

{

int i,a,b;

for(i=0;i<=50;i=i+2)

{

a=i/10;

b=i%10;

cout< ? ? }

return 0;

}

重新編譯運(yùn)行程序,結(jié)果如下:

顯然,程序輸出是正確的。

(3)不要在程序中判斷浮點(diǎn)數(shù)是否相等

例如,判斷數(shù)據(jù)99.6345489和99.6345481的大小,編程如下:

#include

using namespace std;

int main(void)

{

float m = 99.6345489;

float n = 99.6345481;

if(m ? ? cout<<"m ? ? else if(m==n)

cout<<"m==n"< ? ? else

cout<<"m>n"< ? ? return 0;

}

閱讀分析上述程序,程序結(jié)果應(yīng)該“m>n”,但是程序執(zhí)行結(jié)果卻是“m ==n”。結(jié)果出錯(cuò)的原因就是浮點(diǎn)數(shù)無(wú)法表示非常精確的結(jié)果。如程序中的float型變量m和n只能有8位有效數(shù)字,是無(wú)法區(qū)分出末位的9和1。在內(nèi)存中,m和n的二進(jìn)制數(shù)都是0x419F0329。

5 結(jié)束語(yǔ)

本文對(duì)C++程序中浮點(diǎn)數(shù)的使用作了簡(jiǎn)單探討,為了編寫(xiě)出安全、有效的代碼,建議在用高級(jí)語(yǔ)言編寫(xiě)實(shí)際應(yīng)用項(xiàng)目程序時(shí)盡量避免使用浮點(diǎn)型數(shù)據(jù)。

參考文獻(xiàn)

[1] 丁展.C/C++程序設(shè)計(jì)[M].北京:電子工業(yè)出版社,2018.

[2] 比雅尼.C++程序設(shè)計(jì)語(yǔ)言[M].北京:機(jī)械工業(yè)出版社,2002.

[3] 袁春風(fēng).計(jì)算機(jī)系統(tǒng)基礎(chǔ)[M].北京:機(jī)械工業(yè)出版社,2014.

[4] 唐朔飛.計(jì)算機(jī)組成原理[M].北京:高等教育出版社,2008.

[5] 李繼燦.新編16/32位微型計(jì)算機(jī)原理及應(yīng)用.北京:清華大學(xué)出版社,2018.

猜你喜歡
浮點(diǎn)數(shù)存儲(chǔ)精度
四種Python均勻浮點(diǎn)數(shù)生成方法
基于DSPIC33F微處理器的采集精度的提高
在C語(yǔ)言中雙精度浮點(diǎn)數(shù)線性化相等比較的研究
非精確浮點(diǎn)數(shù)乘法器設(shè)計(jì)
檔案管理中電子文件的存儲(chǔ)探究
云計(jì)算與虛擬化
GPS/GLONASS/BDS組合PPP精度分析
改進(jìn)的Goldschmidt雙精度浮點(diǎn)除法器
巧用磨耗提高機(jī)械加工精度
Visual Basic處理浮點(diǎn)DSP芯片數(shù)據(jù)的方法
汾阳市| 榆中县| 宁陕县| 高阳县| 景泰县| 普格县| 沛县| 昂仁县| 上饶县| 曲水县| 寿阳县| 米易县| 林芝县| 白河县| 嘉黎县| 溆浦县| 绥德县| 涞水县| 黄冈市| 临沭县| 辽源市| 锡林郭勒盟| 玉山县| 准格尔旗| 福海县| 石门县| 上虞市| 巍山| 仁怀市| 启东市| 施秉县| 临城县| 灵山县| 怀柔区| 万盛区| 湘西| 江都市| 呼伦贝尔市| 永丰县| 巢湖市| 清水河县|