Pergunta

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 <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;
}
Foi útil?

Solução

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.

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top