while循环没有正确终止

时间:2013-04-28 21:03:21

标签: c++ loops while-loop termination

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

#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 个答案:

答案 0 :(得分: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";
}

答案 1 :(得分:3)

这不起作用的原因是0.2无法在float中精确表示,因为它的小数部分不是2的负幂的精确和。如果您使用其他号码(例如0.25)进行尝试,则代码将有效,因为0.252^-2

答案 2 :(得分:0)

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

更准确地说,0.2无法用double精确表示。它实际上类似于0.1999999...。因为0.2等于1/5,而1/5是二进制表示中的无限分数。 (像1/3是十进制表示中的无限分数)。

答案 3 :(得分:0)

你可以在循环中使用带有浮动强制转换的double,或者你可以使用自定义&lt;自定义你自己的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;

}