2

我怀疑这可能与舍入错误有关,因为我使用双精度来控制循环终止,但我真的想知道发生了什么

#include<iostream>

using namespace std;

int main()
{
  double h = 0.2;  // stepsize                                                                                                                                                                       
  double t_0 = 1;
  double t_n = 25;
  double y_0 = 1;  // initial condition                                                                                                                                                              


  double t = t_0;
  while(t < t_n)
    {
      cout << "t: " << t << endl;
      cout << "(t < t_n): " << (t < t_n) << endl;
      t += h;
    }
}

最后几行输出是

t: 24.4
(t < t_n): 1
t: 24.6
(t < t_n): 1
t: 24.8
(t < t_n): 1
t: 25
(t < t_n): 1

最后一条语句不应该返回false吗?即,循环不应该在 24.8 处终止吗?

4

4 回答 4

3

你是对的,double不是一个确切的类型,你不能指望确切的结果。(典型的例子是 0.1 + 0.1 + 0.1 和 0.3 不一样;它可能更大或更小。)如果可行,首选定点积分算法:

for (int i = 10; i < 250; i += 2)
{
    double t = i / 10.0;
    std::cout << "t: " << t << "\n";
}
于 2013-04-28T21:05:58.977 回答
3

这不起作用的原因是它0.2不能在 a 中精确表示float,因为它的小数部分不是两个负幂的精确总和。如果您尝试使用不同的数字,例如 ,0.25代码将起作用,因为0.25is 2^-2

于 2013-04-28T21:06:32.010 回答
0

您可以在循环中使用 double 和 float 强制转换,也可以使用自定义 < 运算符实例化您自己的 double 类型

#include <iostream>

using namespace std;



class _double
{
    private :
    double d ;

    public :
    _double(double d) { this->d = d ;}
    double get() { return d ;}

_double &operator+=(_double  &a)
    {
        this->d+=a.get();
        return *this;
    }

void display(ostream &out)
    {
    cout << this->d ;
    }
};

bool operator<(_double  &a,_double  &b)
    {
        if ( (float ) a.get() <  (float) b.get()  )
        return true ;
        return false ;
    }



ostream& operator<<(ostream& out, _double & a)
{
    a.display(out) ;
    return out;
}

int main()
{
  double h = 0.2;  // stepsize
  double t_0 = 24;
  int  t_n = 25.;
  double y_0 = 1;  // initial condition

    _double d1(25);
    _double d_t(24);
    _double d_h(0.2);


 cout <<  endl << " =========== First Method ============== " << endl   ;


   double t = t_0;
   while((float) t<(float) t_n)
    {
      cout << "t: " << t<< endl;
      cout << "(t < t_n): " << (t < t_n) << endl;
      t += 0.2;
    }


    cout << " out of loop t: " << t << endl;
    cout << "out of loop ->  (t < t_n): " << (t < t_n) << endl;

     cout << " =========== Second Method ============== " << endl ;


      while( d_t< d1)
    {
      cout << "t: " << d_t<< endl;
      cout << "(t < t_n): " << (d_t < d1) << endl;
      d_t += d_h;
    }



    cout << "out of loop t: " << t << endl;
    cout << "out of loop ->  (t < t_n): " << (t < t_n) << endl;
    return 0;

}
于 2013-04-28T21:56:01.180 回答
0

就像@Kerrek SB 所说,double算术是“不精确的”。

更准确地说,0.2不能用 来精确表示double。它实际上是这样的0.1999999...。因为 0.2 等于 1/5,而 1/5 是二进制表示的无限小数。(就像 1/3 是十进制表示的无限小数)。

于 2013-04-28T21:13:23.233 回答