2010-09-12 122 views
0

我有相當直接的問題。以下代碼打印出攝氏和華氏。 雖然我的問題是迭代的次數。對於少數例如開始0,停在10,步長爲1.1。循環結束後,它將打印出正確的迭代次數。積累錯誤

但是對於大數字0-11000000,在步驟1.1中會打印出錯誤的迭代次數。爲什麼會發生?由於1100000/1.1應該在1000001附近,但我得到了990293.

#include <iostream> 
#include <iomanip> 

using namespace std; 

int main() 
{ 

    float start, stop, step; 
    int count = 0; 

    cout << "start temperature: "; 
    cin >> start; 
    cout << "stop temperature: "; 
    cin >> stop; 
    cout << "step temperature: "; 
    cin >> step; 

    cout << setw(10) << "celsius" << setw(15) << "fahrenheit" << endl; 
    cout << setw(25) << "celsius" << setw(15) << "fahrenheit" << endl; 

    while(start <= stop) 
    { 
     count++; 
     float c, f; 
     c = (5.0/9)*(start-32); 
     f = 32+(9.0/5)*start; 
     cout << setw(10) << fixed << setprecision(2) << c << setw(15) << start << setw(15) << fixed << setprecision(2) << f << " count: " << count << endl; 

     start = start + step; 
    } 
    cout << "The program loop made " << count << " iterations." << endl; 

    return 0; 
} 

回答

5

浮點舍入錯誤。從本質上講,浮點數不是100%準確的表示,每次計算都會有錯誤,並且在重複添加到它們時,會增加越來越多的錯誤。你應該做的是計算一次步數,將它存儲在一個整數中,然後循環多次。

+1

而不是'start = start + step;'你應該用一個整數類型來計算步長,並且從步數中計算浮點值:put'float temp = start + step * count;'在count ++前面;'在你的數學中使用'temp'而不是'start'。還要將循環更改爲'while(start + step * count <= stop)'。 – 2010-09-12 14:42:31

+1

*已刪除*因爲我的評論在我發表評論前得到了答覆 – starzdust 2010-09-12 14:46:13

0

爲了記錄在案,一清理的版本會是什麼樣子:

#include <iostream> 
#include <iomanip> 

using namespace std; 

int main() 
{ 

    double start, stop, step; 

    cout << "start temperature: "; 
    cin >> start; 
    cout << "stop temperature: "; 
    cin >> stop; 
    cout << "step temperature: "; 
    cin >> step; 

    cout << setw(10) << "celsius" << setw(15) << "fahrenheit" << endl; 

    unsigned steps = (stop - start)/step; 

    for(unsigned i = 0; i < steps; ++i) 
    { 
     double temp = start + i * step; 
     double c = (5.0/9.0) * (temp - 32.0); 
     double f = 32.0 + (9.0/5.0) * temp; 
     // This is a real good example of why people hate <iostream> formatting. 
     // If you want formatting that's quite different from the default, it 
     // gets too verbose too fast. Using C stdio: 
     //printf("%10.2f%15.2f\n", c, f); 
     cout << setw(10) << fixed << setprecision(2) << c 
      << setw(15) << fixed << setprecision(2) << f << endl; 
    } 

    cout << "The program loop made " << steps << " iterations." << endl; 

    return 0; 
} 

這種風格環路的主要好處是,每次迭代(除了輸出)順序無關,所以它可能展開並(理論上)並行化。