我有以下c++代码:
float test(0.2);
cout << 1.8 + test << " " << boolalpha << (1.8 + test <= 2) << endl;
和这个输出:
2 false
但问题是我应该有这样的输出:
2 true
如何解决这个问题?
错误在哪里?
这是一个舍入误差。1.8
和0.2
都不能用二进制浮点格式精确表示,因此使用的实际值略有不同。这意味着最终结果可能不完全是2;但将其流式传输到cout
将四舍五入到小数点后几位并打印2
。
你可以通过更精确地打印它来自己看到这一点:
cout << setprecision(20) << 1.8 + test << " " << boolalpha << (1.8 + test <= 2) << endl;
// Output: 2.0000000029802320611 false
生活例子
如何解决这个问题?
这取决于你想用浮点数做什么。通常,你可以允许一个小的错误容忍度,例如
float tolerance = 1e-6;
cout << 1.8 + test << " " << boolalpha << (1.8 + test <= 2 + tolerance) << endl;
但是,一般来说,管理错误和计算可接受的公差可能是一种黑暗的艺术,需要对算法的细节有很好的理解。
解决与浮点运算相关的问题的一种方法是使用阈值来比较是否相等,而不是使用原始值。
也就是说,不像
double a = // some value
double b = // another value
if (a == b)
// ...
执行以下操作
if (abs(a - b) <= 1e-5)
// ...
导致了一些错误。实际的阈值不必完全是1e-5
,您可以选择另一个。