2011-08-12 211 views
1

爲什麼在下面的代碼中打印這個文件從不打印?我已經認識到shiftx和shifty以確保在某些時候它們都是0.3。C++循環打印

for(double shifty=0; shifty < 2; shifty+=.1) { 
    for(double shiftx=0; shiftx < 2; shiftx +=.1) { 
     if((shiftx == 0.3) && (shifty == 0.3)) { 
      cout << "PRINT THIS" << endl; 
     } 
    }  
} 

回答

9

黃金法則是:避免在浮點平等測試。

0.1和0.3都不能精確表示。

標準閱讀:What Every Computer Scientist Should Know About Floating-Point Arithmetic

要解決您的特定問題,您應該使用整數類型進行迭代和執行比較。只有在實際需要時才轉換爲浮點類型。例如:

for(int shifty=0; shifty < 20; shifty++) { 
    for(int shiftx=0; shiftx < 20; shiftx++) { 
     double shifty_double = shifty * 0.1; 
     double shiftx_double = shiftx * 0.1; 
     if((shiftx == 3) && (shifty == 3)) { 
      cout << "PRINT THIS" << endl; 
     } 
    }  
} 
+0

我明白爲什麼這個工程,但如果0.3不能正確代表,你嘗試用.3比3,不會他們都不能正確代表,因此比較等於?還是說它們可以以幾乎不同的方式「幾乎」表現出來,而這只是讓它們平等或不平等的機會? –

+1

@Seth或多或少總結它。它們可以以幾乎不同的方式「表示」,文字值.1和.3將轉換爲編譯器選擇的近似浮點形式,無論.1的浮點形式如何,如果它並不是0.3近似值的1/3,那麼內部循環中的相等性測試將失敗。 – csj

4

這可能是由於使用雙精度時的舍入誤差,因爲0.3在內部實際上並未實際存儲爲0.3。

比較雙打的一種方式是允許比較中出現一些錯誤。 例

if(abs(shiftx - shifty) < 0.000001)