我怀疑这可能与舍入错误有关,因为我正在使用双精度来控制循环终止,但我想知道发生了什么
#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?
答案 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.25
为2^-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;
}