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

2 回答 2

5

浮点舍入误差。从本质上讲,浮点数并不是 100% 准确的表示,您所做的每次计算都会出现错误,并且随着您反复添加它们,您将添加越来越多的错误。您应该做的是计算一次步数,将其存储为整数,然后循环多次。

于 2010-09-12T14:32:27.440 回答
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;
}

这种循环风格的主要好处是每次迭代(除了输出)都是顺序无关的,因此它可以展开和(理论上)并行化。

于 2010-09-12T15:12:04.273 回答