我是C ++的新手。我在阅读C ++时遇到了疑问。 如何判断两个浮点数是否相等?
提前致谢
答案 0 :(得分:5)
您需要知道一个特殊的常量,称为DBL_EPSILON(或FLT_EPSILON)。这是可以添加到 1.0 并更改其值的最小值。值 1.0 非常重要 - 添加到DBL_EPSILON时,较大的数字不会更改。现在,您可以将此值缩放为您要比较的数字,以判断它们是否不同。比较两个双打的正确表达式是:
if (fabs(a-b) <= DBL_EPSILON * fmax(fabs(a), fabs(b)))
{
// ...
}
答案 1 :(得分:2)
如果您的浮点类型使用IEEE 754表示(很可能就是这种情况),那么您应该使用浮点数的二进制表示的顺序与按价值排序。也就是说,如果将浮点数的二进制表示增加一位,则会得到下一个更大的数字。
使用这个事实,我们可以通过计算它们的二进制差异来比较浮点数。这称为“通过最后位置(ULP)进行比较”。有一些微妙的标志,零,无穷大和NaNs,但这是它的要点。这是comprehensive article解释这一点。
基本上,我们认为两个浮点数相等,如果它们在最后一个位置的少数单位不同。连同您的编译器的数学函数的最终位置和您自己的代码的文档,您可以确定哪个截止符合您的需要。
在伪代码中:
double x, y;
// this is type punning, should be done differently in reality
uint64_t ux = *reinterpret_cast<const uint64_t*>(&x);
uint64_t uy = *reinterpret_cast<const uint64_t*>(&y);
return abs(ux - uy) < CUT_OFF; // e.g. CUT_OFF = 3;
上面的代码只是一个粗略的例子,不起作用,你必须在最后的比较之前处理很多特殊情况。有关详细信息,请参阅文章。
答案 2 :(得分:1)
显然,您不应该使用operator ==
来比较它们。
这里的重要概念是,如果两个浮点数的差值足够小到你要求解决的问题的精度要求或小于你的误差范围,我们应该认为它们是相等的。
有一些实用的方法建议,如
fabs(f1 - f2) < precision-requirement
fabs(f1 - f2) < max(fabs(f1), fabs(f2)) * percentage-precision-requirement