开发者

accumulation error

I have quite straight forward question. The following code prints out celsius and fahrenheit. My question is though about number of times it iterate. For a small number e.g. start 0, stop at 10, with a step of 1.1. After the loop is finished it will print out the correct number of iterations it made.

But for large number 0-11000000, with step 1.1 it will print out wrong number of iteration. Why is that happening? Since 1100000/1.1 should be around 1000001, but I get 990293.

#include <iostream>
#include <ioma开发者_JAVA技巧nip>

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;
}


Floating-point rounding error. Essentially, floats are not a 100% accurate representation, there are errors in every calculation you make, and as you repeatedly add to them, you will be adding more and more error. What you should do is compute the number of steps once, store it in an integer, and then loop that many times.


For the record, a cleaned-up version would look like:

#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;
}

The main benefit of this style of loop is that each iteration is (except for the output) order-independent, so it could be unrolled and (theoretically) parallelized.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜