[英]Comparing floats in c++
我正在從教程中學習 c++,在那里,有人告訴我比較 c++ 中的浮點數可能非常令人困惑。 例如,在下面的代碼中:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == 1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
我會得到“不相等”。 我同意這一點。 導師告訴如果我們需要比較浮點數,我們可以使用 > 到最接近的數字。 (這不是很精確)。 我在谷歌搜索了不同的方法來比較浮點數,我得到了許多復雜的方法來做到這一點。
然后我自己創建了一個程序:
#include <iostream>
using namespace std;
int main()
{
float decimalNumber = 1.2;
if (decimalNumber == (float)1.2){
cout << "Equal" << endl;
}else{
cout << "Not equal" << endl;
}
return 0;
}
在像上面那樣進行類型轉換之后,我得到了“Equal”。
我想知道的是我應該使用上述方法來比較我所有程序中的浮點數嗎? 這有一些缺點嗎?
注意:我知道數字在 memory 中的精確表示方式以及另一個SO Question中描述的 0.1 + 0.2.- 0.3 的方式。 我只想知道我可以通過上述方式檢查兩個浮點數的相等性嗎?
我想知道的是我應該使用上述方法來比較我所有程序中的浮點數嗎?
取決於上下文。 等式比較對浮點數很少有用。
但是,是的,無論是比較相等性還是關系性,都應該比較相同類型的浮點對象,而不是混合浮點數和雙精度數。
這有一些缺點嗎?
浮點計算可能有錯誤。 結果可能不是你所期望的。 當有錯誤時,相等比較是沒有意義的。
第二個例子起作用的原因在某種程度上純粹是偶然的。
需要考慮的一些因素:
當比較的雙方都是float
類型時,編譯器可能更有可能“優化”比較,以便它只發生在編譯過程中。 它可以查看文字並意識到這兩個數字在邏輯上是相同的,即使在運行時它們可能在較低的精度級別上有所不同。
當比較的兩邊都是float
類型時,它們具有相同的精度,因此如果您以相同的方式(這里,通過文字)創建值,則較低精度級別的任何錯誤都可能相同。 當其中一個是double
時,最后會有額外的錯誤位導致比較失敗。 如果您通過0.6 + 0.6
創建了一個,那么結果也可能不同,因為錯誤傳播方式不同。
一般來說,不要依賴這個。 當浮點數包含不能以二進制精確表示的數字時,您無法真正預測它們的“准確度”。 如果您需要松散的值比較,您應該堅持使用 epsilon-range 比較(在適當的情況下),即使直接比較在沒有它的情況下偶爾會“起作用”。
如果您實際上不需要浮點數,一個好方法是使用定點數。 該語言中沒有內置的定點類型,但這沒關系,因為您可以通過一些算術簡單地模擬它們。 很難知道您的用例是什么,但是如果您只需要一位小數,則可以存儲int decimalNumber = 12
(即,將小數點移動一位)並在需要顯示時除以十。 兩個值為12
的int
總是比較好。
金錢就是一個很好的例子:用便士(或十分之一便士)而不是英鎊來計算,以避免在騙取客戶現金時出現錯誤。
默認情況下,在 C++ 中,浮點數與浮點變量相比被視為double
精度數。 您需要使用f
后綴告訴編譯器該數字是浮點數而不是double
。 舉個例子:
#include <iostream>
int main(void) {
float dec = 1.2;
if (dec == 1.2f)
std::cout << "Equal";
else
std::cout << "Unequal";
return 0;
}
它會產生Equal
。 OTOH,如果您不使用f
后綴,則比較將等效於:
if (dec == 1.199999999999999956) // 1.2 converted into double
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.