2013-10-06 24 views
0

浮點數對比我有一個循環來爲後續關於C++

#include <iostream> 
using namespace std; 

void main(void) 
{ 
    for (double x=0.012; x<=0.013; x+=0.001) 
    { 
    cout << x << endl; 
    } 
} 

給出的最小和最大範圍之間的浮點數這是很簡單的代碼,但我知道在計算機語言中,我們需要比較考慮EPS的兩個浮動數字。因此,上面的代碼不起作用(我們期望它從0.012到0.013循環兩次,但它只循環一次)。所以我手動添加一個EPS到上限。

#include <iostream> 
using namespace std; 
#define EPS 0.0000001 

void main(void) 
{ 
    for (double x=0.012; x<=0.013+EPS; x+=0.001) 
    { 
    cout << x << endl; 
    } 
} 

它現在起作用。但是手動操作看起來很難看,因爲EPS實際上取決於機器。我將我的代碼從matlab移植到C++,並且我沒有matlab中的問題,因爲有eps命令。但是在C/C++中有這樣的嗎?

+1

不,沒有內置任何東西。浮點容差和錯誤處理取決於應用程序。 – Barmar

+7

而不是迭代浮點值,迭代整數,然後除以1000.0得到分數。 – Barmar

+0

支持@ Barmar的評論。累積浮點加法會累積舍入誤差。對於更大的迭代次數,EPS可能需要更大。同時,你可以用整數表達你想要的迭代次數。 –

回答

3

對比錯是錯誤的使用方法。即使您得到「正確」的比較,浮點循環計數器也會累積從迭代到迭代的錯誤。

您可以通過使用循環計數器的精確算術來消除錯誤累積。它可能仍然有浮點類型,但是你用精確表示的值,如:

for (double i = 12; i <= 13; ++i) 

然後,在循環中,您縮放爲所需的計數器:

for (double i = 12; i <= 13; ++i) 
{ 
    double x = i/1000.; 
    … 
} 

顯然,有沒有太多的錯誤積累在一個循環中兩次迭代。但是,我希望你的價值觀只是一個例子,實踐中可能會有更長的循環。使用這種技術,x中唯一的錯誤是在縮放操作中,所以在每次迭代中只有一個錯誤,而不是每次迭代一次。

請注意,除以1000會比按比例縮放0.001更準確。 1000分區只有一個錯誤(在分區中)。但是,由於.001在二進制浮點中不能完全表示,所以乘以它會有兩個錯誤(在.001到浮點的轉換和乘法運算中)。另一方面,劃分通常是一個非常緩慢的操作,所以你可以選擇乘法。由於縮放中的舍入誤差,儘管該技術保證了所需的迭代次數,但縮放值可能會在第一次或最後一次迭代中的理想目標區間之外輕微變化。如果這對您的應用程序很重要,則必須調整這些迭代中的值。