2013-07-06 98 views
-6

考慮下面的語句:爲什麼此浮點比較評估爲false?

float x = 0.1 + 0.1; 
if (x == 0.2) 
    return true; 
else 
    return false; 

如果它不評估爲真?
由於0.1 + 0.1等於0.2!

+2

見本:http://stackoverflow.com/questions/7011184/浮點比較 – banarun

+5

我發誓,這是我在過去24小時內見過的這種類型的第10個浮點問題。這是暑期班的主題嗎? – Mysticial

+3

有一個關於這個[問題](http://stackoverflow.com/questions/17500455/float-and-double-value-creating-confusion-in-c)的問題,並在幾分鐘前作爲一個副本關閉。它收穫了很多。閱讀「每個計算機科學家應該瞭解的浮點算術」,這很容易找到。 –

回答

2

在您的計算機上試試這個。你會得到答案的提問:

if(0.2==0.2f) 
    printf("Yes\n"); 
else 
    printf("NO\n"); 
+1

Upvoted作爲其中一個答案強調轉換爲浮動是OP的例子中的不精確操作。 –

4

不,浮點數不是數學實數。

O.1不是二進制精確表示(具有有限分數位的數目),所以不會在IEEE 754

作爲一個經驗法則精確表示,平等試驗應幾乎從未被用於floatdouble浮動 - 點的數字(除了奇怪成語:if (x != x)來測試xNaN)也

見的Fluctuat靜態分析器和Some disasters caused by numerical errors。也許考慮使用bignums

如果您碰巧需要浮點數,請詳細瞭解它們。 Floating point號碼是一個可怕的話題。

+0

謝謝那麼如果我們需要使用浮點相等性測試而不能避免呢? – Breeze

+0

本質上浮點平等沒有意義。 –

+2

@Hossein,http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm – chris

1

嘗試使用下面的代碼:比較期間

float x = 0.1 + 0.1; 
if (x == .2) 
    return true; 
else 
    return false; 

花車得到提升到雙打,和彩車比雙打不太精確。

+3

'if(bool_expr)return true;否則返回false;'是**冗餘**,因此**顯式錯誤,**只是'返回the_bool_expr;'本身。 – 2013-07-06 07:11:29

+0

我剛剛對有問題的代碼進行了修改。否則,我完全同意你的看法 –

+0

夠公平的,我應該把這個評論留給OP的問題(太)。 – 2013-07-06 07:14:38

3

你的0.1可以很容易地取爲0.0999999或0.1000001,它不等於0.1,這使得它很難等於0.2(也可能是0.1999或0.2001)。

結果是確定的,所以如果你沒有得到預期可以在第一次比較,如果你一直比較同樣的事情,你不能再得到。(吉姆·巴爾特的評論)

您需要檢查的範圍,如X >(0.2-0.001)和x <(0.2 + 0.001)

if((x>(0.2-0.001)) &&(x<(0.2+0.001))) 
{ 

} 

+/- 0.001這裏是您的誤差範圍爲您希望採取的間隔。不要忘記,0.2是一個雙倍和你的「x」促進雙倍比較之前。當促進翻番時,甚至可以改變更多。所以你完全不知道你是否可以比較一個確切的值。

如果你需要更接近x,那麼你需要選擇一個小於0.001的值。如果你增加了機會,那麼使用更大的時間間隔(例如:+/- 0.01)。 這可能更像是「寬容」vs「精確」的問題來辯論。

如果您需要比較float和float,請在每個常量字面的末尾加上一個「f」,就像「x> = 20.01f」一樣。

看看arithmetic underflowarithmetic overflow,這樣你就可以更加確定你在做什麼。

一些更多的信息:floating point

+0

」爲了得到那個幸運,你需要數百萬次嘗試「 - 不,它是確定性的;答案永遠是一樣的。 –

+0

好的改變了那個部分。謝謝。 –

相關問題