基于C++浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換的詳解
更新時間:2013年05月16日 17:00:47 作者:
本篇文章是對C++中浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
浮點(diǎn)數(shù)在內(nèi)存中的存儲機(jī)制和整型數(shù)不同,其有舍入誤差,在計算機(jī)中用近似表示任意某個實(shí)數(shù)。具體的說,這個實(shí)數(shù)由一個整數(shù)或定點(diǎn)數(shù)(即尾數(shù))乘以某個基數(shù)(計算機(jī)中通常是2)的整數(shù)次冪得到,這種表示方法類似于基數(shù)為10的科學(xué)記數(shù)法。
所以浮點(diǎn)數(shù)在運(yùn)算過程中通常伴隨著因?yàn)闊o法精確表示而進(jìn)行的近似或舍入。但是這種設(shè)計的好處是可以在固定的長度上存儲更大范圍的數(shù)。
1、將字符串轉(zhuǎn)換為float、double過程存在精度損失,只是float、double各自損失的精度不相同而已
std::string str="8.2";
float cc=atof(str.c_str()); //cc的值為8.1999998
std::string str="8.2";
double cc=atof(str.c_str()); //cc的值為8.1999999999999993
2、將float、double轉(zhuǎn)換為字符過程中可能存在精度損失,但是通過%.8lf可以規(guī)避
(1)float小數(shù)點(diǎn)前后加起來有效數(shù)字只有6位。當(dāng)給定的float有效數(shù)在6位以內(nèi)轉(zhuǎn)換為字符不會丟失精度,當(dāng)有效位數(shù)大于6位就會存在精度丟失
//精度沒有丟失
char buf[100]={'\0'};
float aa=8000.25;
sprintf(buf,"%f",aa); //8000.250000
//精度沒有丟失
char buf[100]={'\0'};
float aa=8.00025;
sprintf(buf,"%f",aa); buf = 8.000250
//精度丟失,存在誤差
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%f",aa); //8000.250977
//精度丟失,存在誤差此時使用.8lf也無效
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%.8lf",aa); //8000.25097656
(2)double小數(shù)前后加起來的有效數(shù)字只有16位,當(dāng)給定的double有效數(shù)在16位以內(nèi)轉(zhuǎn)換為字符串不會丟失精度,當(dāng)有效位數(shù)大于16位湖影公寓存在精度丟失
存在誤差
char buf[100]={'\0'};
double aa=121.437565871234012;
sprintf(buf,"%.20lf",aa); //121.43756587123401000000
//沒有誤差
char buf[100]={'\0'};
double aa=8000.256165;
sprintf(buf,"%.8lf",aa);
std::cout <<buf<<std::endl; //8000.25616500
3、浮點(diǎn)數(shù)比較
用"=="來比較兩個double應(yīng)該相等的類型,返回真值完全是不確定的。計算機(jī)對浮點(diǎn)數(shù)的進(jìn)行計算的原理是只保證必要精度內(nèi)正確即可。
我們在判斷浮點(diǎn)數(shù)相等時,推薦用范圍來確定,若x在某一范圍內(nèi),我們就認(rèn)為相等,至于范圍怎么定義,要看實(shí)際情況而已了,float,和double 各有不同
所以const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON) 這樣判斷是可取的
至于為什么取0.00001,可以自己按實(shí)際情況定義
根據(jù)上面分析建議在系統(tǒng)開發(fā)過程中設(shè)計到字符轉(zhuǎn)換建議采用double類型,精度設(shè)置為%.8lf即可,在比較浮點(diǎn)數(shù)十建議EPSINON = 0.00000001
所以浮點(diǎn)數(shù)在運(yùn)算過程中通常伴隨著因?yàn)闊o法精確表示而進(jìn)行的近似或舍入。但是這種設(shè)計的好處是可以在固定的長度上存儲更大范圍的數(shù)。
1、將字符串轉(zhuǎn)換為float、double過程存在精度損失,只是float、double各自損失的精度不相同而已
std::string str="8.2";
float cc=atof(str.c_str()); //cc的值為8.1999998
std::string str="8.2";
double cc=atof(str.c_str()); //cc的值為8.1999999999999993
2、將float、double轉(zhuǎn)換為字符過程中可能存在精度損失,但是通過%.8lf可以規(guī)避
(1)float小數(shù)點(diǎn)前后加起來有效數(shù)字只有6位。當(dāng)給定的float有效數(shù)在6位以內(nèi)轉(zhuǎn)換為字符不會丟失精度,當(dāng)有效位數(shù)大于6位就會存在精度丟失
//精度沒有丟失
char buf[100]={'\0'};
float aa=8000.25;
sprintf(buf,"%f",aa); //8000.250000
//精度沒有丟失
char buf[100]={'\0'};
float aa=8.00025;
sprintf(buf,"%f",aa); buf = 8.000250
//精度丟失,存在誤差
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%f",aa); //8000.250977
//精度丟失,存在誤差此時使用.8lf也無效
char buf[100]={'\0'};
float aa=8000.251;
sprintf(buf,"%.8lf",aa); //8000.25097656
(2)double小數(shù)前后加起來的有效數(shù)字只有16位,當(dāng)給定的double有效數(shù)在16位以內(nèi)轉(zhuǎn)換為字符串不會丟失精度,當(dāng)有效位數(shù)大于16位湖影公寓存在精度丟失
存在誤差
char buf[100]={'\0'};
double aa=121.437565871234012;
sprintf(buf,"%.20lf",aa); //121.43756587123401000000
//沒有誤差
char buf[100]={'\0'};
double aa=8000.256165;
sprintf(buf,"%.8lf",aa);
std::cout <<buf<<std::endl; //8000.25616500
3、浮點(diǎn)數(shù)比較
用"=="來比較兩個double應(yīng)該相等的類型,返回真值完全是不確定的。計算機(jī)對浮點(diǎn)數(shù)的進(jìn)行計算的原理是只保證必要精度內(nèi)正確即可。
我們在判斷浮點(diǎn)數(shù)相等時,推薦用范圍來確定,若x在某一范圍內(nèi),我們就認(rèn)為相等,至于范圍怎么定義,要看實(shí)際情況而已了,float,和double 各有不同
所以const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON) 這樣判斷是可取的
至于為什么取0.00001,可以自己按實(shí)際情況定義
根據(jù)上面分析建議在系統(tǒng)開發(fā)過程中設(shè)計到字符轉(zhuǎn)換建議采用double類型,精度設(shè)置為%.8lf即可,在比較浮點(diǎn)數(shù)十建議EPSINON = 0.00000001
您可能感興趣的文章:
- C++數(shù)據(jù)精度問題的解決方案(對浮點(diǎn)數(shù)保存指定位小數(shù))
- C++數(shù)據(jù)精度問題(對浮點(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)存中的存儲方式詳解
- C++浮點(diǎn)型的存儲方式詳解
- C++浮點(diǎn)數(shù)在內(nèi)存中的存儲詳解
- C/C++浮點(diǎn)數(shù)使用的兩個注意事項(xiàng)詳解
- C++中浮點(diǎn)類型的具體使用
相關(guān)文章
C++ 實(shí)現(xiàn)即時通信的示例代碼(直接運(yùn)行)
本文主要介紹了C++ 實(shí)現(xiàn)即時通信的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05