C/C++浮點數(shù)使用的兩個注意事項詳解
一.回顧浮點數(shù)的存儲與讀取
浮點數(shù)的存入與讀取流程總覽:
二.浮點數(shù)使用的第一個注意事項
由于浮點數(shù)存入時很可能發(fā)生有效數(shù)值M二進制序列的截斷以及被截去的序列的最高位的四舍五入而造成精度損失,所以兩個浮點數(shù)直接用操作符進行比較很可能會得到不符合預期的結果。
舉個例子:
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的值在數(shù)學上應該是相同的,但是由于精度丟失而導致了最后a<b,如果這時a和b直接用運算符進行比較則無法得到預期的結果。
兩個浮點數(shù)的比較應該使用如下方式:
對于浮點數(shù)而言比較合適的精度為:0.000001
對于雙進度浮點數(shù)而言比較合適的精度為:0.0000000000000001
因此可以定義兩個宏:
#define epf 1e-6 #define epd 1e-16
f,f1,f2代表單精度浮點數(shù),d,d1,d2代表雙精度浮點數(shù)。
判斷浮點數(shù)是否等于0:
要判斷一個單精度浮點數(shù)是否等于0:if(fabs(f) <= eps );
要判斷一個雙精度浮點數(shù)是否等于0:if(fabs(d) <= epd);
判斷兩個浮點數(shù)是否相等:
要判斷兩個單精度浮點數(shù)是否相等:if(fabs(f1 - f2) <= eps);
要判斷兩個雙精度浮點數(shù)是否相等:if(fabs(d1 - d2) <= epd);
注:fabs是求浮點數(shù)絕對值的函數(shù)。聲明在<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; }
三.浮點數(shù)使用的第二個注意事項
由于浮點數(shù)存入時可能發(fā)生數(shù)據(jù)截斷,因此兩個絕對值相差巨大的浮點數(shù)進行加減運算很多時候是沒有意義的。
以十進制數(shù)為例來說明這個問題:
代碼驗證:
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都被宏定義為浮點數(shù)絕對值最大的值
將FLT_MAX存入內存中:
將a的二進制序列分割為SEM的形式 :
其指數(shù)位不是全1
C/C++中的FLT_MIN被宏定義為絕對值最接近于0的浮點數(shù)
將FLT_MIN存入內存中:
其指數(shù)位不是全0
補充:C 語言兩個浮點數(shù)比較大小的辦法
浮點數(shù)并非真正意義上的實數(shù),只是其在某個范圍內的近似。
因此兩個浮點數(shù)比較大小時,不能簡單地使用大于小于號進行比較,應該判斷連個浮點數(shù)差值的絕對值是否近似為0。
#include <stdio.h> #include <math.h> // 這里的 EPS 是自己定義的精度 #define EPS 1e-7 // 判斷浮點數(shù)是否位于0的一個很小的鄰域內[-EPS,EPS]內 int main(void) { /* 判斷一個浮點數(shù)是否等于 0*/ float a; scanf("%f", &a); if(fabs(a) <= EPS) // a=0 ... else if(a > EPS) // a>0 ... else // a<0 ... /* 比較兩個浮點數(shù)大小 */ 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 ... }
總結
到此這篇關于C/C++浮點數(shù)使用的兩個注意事項的文章就介紹到這了,更多相關C/C++浮點數(shù)注意事項內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++深入探究哈希表如何封裝出unordered_set和unordered_map
哈希表是一種根據(jù)關鍵碼去尋找值的數(shù)據(jù)映射結構,該結構通過把關鍵碼映射的位置去尋找存放值的地方,說起來可能感覺有點復雜,我想我舉個例子你就會明白了,最典型的的例子就是字典2022-06-06CMake 生成靜態(tài)庫與動態(tài)庫的方法步驟
本文主要介紹了CMake 生成靜態(tài)庫與動態(tài)庫的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06采用C++實現(xiàn)區(qū)間圖著色問題(貪心算法)實例詳解
這篇文章主要介紹了采用C++實現(xiàn)區(qū)間圖著色問題(貪心算法),很經(jīng)典的算法問題,需要的朋友可以參考下2014-07-07