C++ 常见问题解答精简版“[29.17] 为什么我的浮点比较不起作用?”推荐这个平等测试:
#include <cmath> /* for std::abs(double) */
inline bool isEqual(double x, double y)
{
const double epsilon = /* some small number such as 1e-5 */;
return std::abs(x - y) <= epsilon * std::abs(x);
// see Knuth section 4.2.2 pages 217-218
}
- 这是否意味着唯一等于零的数字是
+0
and -0
?
- 在测试零或类似测试时是否也应该使用此函数
|x| < epsilon
?
Update
正如 Daniel Daranas 所指出的,该函数可能最好被调用isNearlyEqual
(这是我关心的情况)。
有人指出《比较浮点数》,我想更突出地分享这一点。
你的观察是正确的。
If x == 0.0
, then abs(x) * epsilon
为零,您正在测试是否abs(y) <= 0.0
.
If y == 0.0
那么你正在测试abs(x) <= abs(x) * epsilon
这意味着要么epsilon >= 1
(不是)或x == 0.0
.
所以要么is_equal(val, 0.0)
or is_equal(0.0, val)
毫无意义,你可以说val == 0.0
。如果你只想接受exactly +0.0
and -0.0
.
在这种情况下,常见问题解答的建议作用有限。不存在“一刀切”的浮点比较。您必须考虑变量的语义、可接受的值范围以及计算引入的误差大小。甚至常见问题解答也提到了一个警告,称“当 x 和 y 的大小明显大于 epsilon 时,此函数通常不是问题,但您的里程可能会有所不同”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)