日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C/C++浮點數使用的兩個注意事項詳解_C 語言

作者:擺爛小青菜 ? 更新時間: 2023-04-07 編程語言

一.回顧浮點數的存儲與讀取

浮點數的存入與讀取流程總覽:

二.浮點數使用的第一個注意事項

由于浮點數存入時很可能發生有效數值M二進制序列的截斷以及被截去的序列的最高位的四舍五入而造成精度損失,所以兩個浮點數直接用操作符進行比較很可能會得到不符合預期的結果。

舉個例子:

int main()
{
    float a = 3.12f;
    a += 0.02f;
   
    float b = 3.14f;
 
    std::cout << (a == b) << std::endl;
    std::cout << (a > b) << std::endl;
    std::cout << (a < b) << std::endl;
 
    return 0;
}

簡單調試一下代碼:

上述代碼中,a最終的值和b的值在數學上應該是相同的,但是由于精度丟失而導致了最后a<b,如果這時a和b直接用運算符進行比較則無法得到預期的結果。

兩個浮點數的比較應該使用如下方式:

對于浮點數而言比較合適的精度為:0.000001

對于雙進度浮點數而言比較合適的精度為:0.0000000000000001

因此可以定義兩個宏:

#define epf 1e-6
#define epd 1e-16

f,f1,f2代表單精度浮點數,d,d1,d2代表雙精度浮點數。

判斷浮點數是否等于0:

要判斷一個單精度浮點數是否等于0:if(fabs(f) <= eps );
要判斷一個雙精度浮點數是否等于0:if(fabs(d) <= epd);
判斷兩個浮點數是否相等:

要判斷兩個單精度浮點數是否相等:if(fabs(f1 - f2) <= eps);
要判斷兩個雙精度浮點數是否相等:if(fabs(d1 - d2) <= epd);

注:fabs是求浮點數絕對值的函數。聲明在<iostream>頭文件中。

#define eps 1e-6
int main()
{
    float a = 3.12f;
    a +=0.02f;
    float b = 3.14f;
    if (fabs(a - b) <= eps)
    {
        std::cout << "a==b" << std::endl;
    }
    else
    {
        std::cout << "a!=b" << std::endl;
    }
    return 0;
}

三.浮點數使用的第二個注意事項?

由于浮點數存入時可能發生數據截斷,因此兩個絕對值相差巨大的浮點數進行加減運算很多時候是沒有意義的。

以十進制數為例來說明這個問題:

代碼驗證:

int main()
{
    float a = 1e38;
    std::cout << a << std::endl;
    
    float b = 1000;
    a = a + b;
    std::cout << a << std::endl;
 
    a = a - b;
    std::cout << a << std::endl;
    return 0;
}

附: 觀察內存中的FLT_MAX和FLT_MIN

C/C++中的FLT_MAX都被宏定義為浮點數絕對值最大的值

將FLT_MAX存入內存中:

將a的二進制序列分割為SEM的形式 :

其指數位不是全1

C/C++中的FLT_MIN被宏定義為絕對值最接近于0的浮點數?

將FLT_MIN存入內存中:

其指數位不是全0?

補充:C 語言兩個浮點數比較大小的辦法

浮點數并非真正意義上的實數,只是其在某個范圍內的近似。

因此兩個浮點數比較大小時,不能簡單地使用大于小于號進行比較,應該判斷連個浮點數差值的絕對值是否近似為0。

#include <stdio.h>
#include <math.h>
 
// 這里的 EPS 是自己定義的精度
#define EPS 1e-7     // 判斷浮點數是否位于0的一個很小的鄰域內[-EPS,EPS]內

int main(void)
{
    /* 判斷一個浮點數是否等于 0*/
    float a;
    scanf("%f", &a);
    if(fabs(a) <= EPS)  // a=0
        ...
    else if(a > EPS)    // a>0
        ...
    else                // a<0
        ...
 
    /* 比較兩個浮點數大小 */
    float a,b;
    scanf("%f%f",&a, &b);
    if(fabs(a-b) <= EPS)  // a=b
        ...
    else if( (a-b) > EPS)  // a>b
        ...
    else                   // a<b
        ...
}

總結

原文鏈接:https://blog.csdn.net/weixin_73470348/article/details/128707623

欄目分類
最近更新