1. 程式人生 > >C++浮點數(float、double)型別資料比較

C++浮點數(float、double)型別資料比較

點數在記憶體中的儲存機制和整型數不同,其有舍入誤差,在計算機中用近似表示任意某個實數。具體的說,這個實數由一個整數或定點數(即尾數)乘以某個基數(計算機中通常是2)的整數次冪得到,這種表示方法類似於基數為10的科學記數法。所以浮點數在運算過程中通常伴隨著因為無法精確表示而進行的近似或舍入。但是這種設計的好處是可以在固定的長度上儲存更大範圍的數。
1、將字串轉換為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轉換為字元過程中可能存在精度損失,但是通過%.8lf可以規避
(1)float小數點前後加起來有效數字只有6位

。當給定的float有效數在6位以內轉換為字元不會丟失精度,當有效位數大於6位就會存在精度丟失
    //精度沒有丟失
    char buf[100]={'\0'};
    float aa=8000.25;
    sprintf(buf,"%f",aa);   //8000.250000
    //精度沒有丟失
    char buf[100]={'\0'};
    floataa=8.00025;
    sprintf(buf,"%f",aa);   buf = 8.000250
    //精度丟失,存在誤差
    charbuf[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小數前後加起來的有效數字只有16位
,當給定的double有效數在16位以內轉換為字串不會丟失精度,當有效位數大於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、浮點數比較

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

用"=="來比較兩個double應該相等型別,返回真值完全是不確定的。計算機對浮點數的進行計算的原理是隻保證必要精度內正確即可。

我們在判斷點數相等時,推薦用範圍來確定,若x在某一範圍內,我們就認為相等,至於範圍怎麼定義,要看實際情況而已了,float,和double 各有不同
    所以const float EPSINON = 0.00001;
    if((x >= - EPSINON) && (x <= EPSINON) 這樣判斷是可取的至於為什麼取0.00001,可以自己按實際情況定義。

    也可以 abs(x) <= EPSINON

比如要判斷點數floatA和B是否相等,我們先令float  x = A –B ;

並設constfloat EPSINON = 0.00001;  則

if ((x >= - EPSINON)&& (x <= EPSINON);//或者if(abs(x) <= EPSINON)

cout<<”A 與B相等<<endl;

else

cout<<”不相等”<<endl;

根據上面分析建議在系統開發過程中設計到字元轉換建議採用double型別,精度設定為%.8lf即可,在比較點數十建議EPSINON= 0.00000001