Frage

Ich habe ganz direkte Frage. Der folgende Code druckt Celsius und Fahrenheit aus. Meine Frage ist zwar ungefähr die Anzahl der Zeiten. Für eine kleine Zahl, z. B. Start 0, halten Sie bei 10 mit einem Schritt von 1,1 an. Nach Abschluss der Schleife wird die richtige Anzahl von Iterationen ausgedehnt, die sie gemacht hat.

Für die große Zahl 0-11000000 wird jedoch mit Schritt 1.1 falsche Anzahl der Iteration ausgedrucken. Warum passiert das? Da 1100000/1.1 etwa 1000001 sein sollte, aber ich bekomme 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;
}
War es hilfreich?

Lösung

Schwimmpunktrundungsfehler. Im Wesentlichen sind Floats keine 100% genaue Darstellung, es gibt Fehler in jeder Berechnung, die Sie durchführen, und wenn Sie sie wiederholt hinzufügen, werden Sie immer mehr Fehler hinzufügen. Was Sie tun sollten, ist die Anzahl der Schritte einmal zu berechnen, sie in einer Ganzzahl zu speichern und dann so oft zu schleifen.

Andere Tipps

Für die Aufzeichnung würde eine aufgeräumte Version so aussehen wie:

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

Der Hauptvorteil dieses Schleifungsstils besteht darin, dass jede Iteration (mit Ausnahme der Ausgabe) ordnungsunabhängig ist, sodass sie abgerollt und (theoretisch) parallelisiert werden kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top