当我编写一个我需要时间数组的小ODE求解器时,我最终得到了以下非常奇怪的行为。以下代码应该清楚地重现问题。
#include <iostream>
using namespace std;
int main() {
double t = 0.0;
for (t = 0.0; t <= 1.00; t += 0.01) {
cout << t << " ";
}
cout << endl;
cout << "t = "<< t << " and t <= 1.00? " << (t <= 1.00) << endl;
double c = 1.00;
cout << "c = "<< c << " and c <= 1.00? " << (c <= 1.00) << endl;
cout << "t == 1.00? " << (t == 1.00) << " and c == 1.00? " << (c == 1.00) << endl;
return 0;
}
这给出了以下输出:
0 0.01 0.02 0.03 0.04 ... 0.97 0.98 0.99
t = 1 and t <= 1.00? 0
c = 1 and c <= 1.00? 1
t == 1.00? 0 and c == 1.00? 1
我的问题是:为什么(t <= 1.00)和(t == 1.00)返回false而t应该明显等于1而t是double类型?
我无法真正避免这个问题,因为在我的实际代码中,我的t-step不是硬编码等...
事先谢谢你。
编辑:谢谢你的回答。确实,0.01等二进制表示的问题不是精确但具有某种舍入误差的问题。 t标度实际上是由程序中的其他物理量强制执行的。在此期间我得到的另一个答案/暗示是,如果需要使用浮点成员,那么总是使用容差。在这种情况下&#34; t&lt; = 1.00&#34;可能变成&#34; t&lt; 1.00 + 0.01 / 2&#34;或更一般的&#34; t&lt; 1.00 + h / 2&#34;当我在我的应用程序中使用变量精度h时。
答案 0 :(得分:2)
浮点运算并不像您期望的那样工作。
罪魁祸首是你在for循环中的条件:
t <= 1.00
t
为double
,因此添加0.01到0.00的100倍并不完全等于1.00但大致等于它。
你可以这样解决:
int t;
for (t = 0; t <= 100; t++) {
std::cout << static_cast<double>(t)/100 << " ";
}
然后:
std::cout << "t = "<< static_cast<double>(t)/100 << " and t <= 1.00? " << (static_cast<double>(t)/100 <= 1) << std::endl;