Question

J'ai une question assez simple. Le code suivant imprime Celsius et Fahrenheit. Ma question concerne le nombre de fois qu'il itère. Pour un petit nombre, par exemple, démarrez 0, arrêtez à 10, avec une étape de 1.1. Une fois la boucle terminée, il imprimera le nombre correct d'itérations qu'il a faites.

Mais pour un grand nombre 0-11000000, avec l'étape 1.1, il imprimera le mauvais numéro d'itération. Pourquoi cela se passe-t-il? Puisque 1100000 / 1.1 devrait être d'environ 1000001, mais j'obtiens 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;
}
Était-ce utile?

La solution

Erreur d'arrondi à point flottante. Essentiellement, les flotteurs ne sont pas une représentation à 100% précise, il y a des erreurs dans chaque calcul que vous faites, et comme vous y ajoutez à plusieurs reprises, vous ajouterez de plus en plus d'erreur. Ce que vous devez faire, c'est calculer le nombre d'étapes une fois, le stocker dans un entier, puis faire bouclez cela plusieurs fois.

Autres conseils

Pour mémoire, une version nettoyée ressemblerait à:

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

Le principal avantage de ce style de boucle est que chaque itération est (sauf pour la sortie) indépendante de l'ordre, il pourrait donc être déroulé et (théoriquement) parallélisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top