以this问题为基础,众所周知,我们不应将等于比较运算的十进制变量应用于数字错误(它不受编程语言约束):
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
abouve代码不对。 我的问题是:
例如:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4);
double b = round(B,4)
return a == b;
}
这是对的吗?
修改
我正在考虑round是一个采用double(number)和int(precition)的方法:
bool round (float number, int precision);
修改 我认为用这个比较方法可以更好地理解我对这个问题的意思:
bool CompareDoubles1 (double A, double B, int precision)
{
//precition could be the error expected when rounding
double a = round(A,precision);
double b = round(B,precision)
return a == b;
}
答案 0 :(得分:5)
通常,如果您真的需要比较浮动值,则需要指定容差:
bool CompareDoubles1 (double A, double B, double tolerance)
{
return std::abs(A - B) < tolerance;
}
选择合适的容差取决于值的性质和产生它们的计算。
舍入是不合适的:两个非常接近的值,你想要比较相等,可能会在不同的方向上舍入并且看起来不相等。例如,当舍入到最接近的整数时,0.3
和0.4
会比较相等,但0.499999
和0.500001
则不会。
答案 1 :(得分:4)
双打的常见比较实现为
bool CompareDoubles2 (double A, double B)
{
return std::abs(A - B) < 1e-6; // small magic constant here
}
它显然不如支票A == B
有效,因为它涉及更多步骤,即减法,调用std :: abs并最终与常量进行比较。
关于效率的相同论点适用于您提出的解决方案:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4); // the magic constant hides in the 4
double b = round(B,4); // and here again
return a == b;
}
同样,这不会像直接比较那样有效,但是 - 再次 - 它甚至不会尝试做同样的事情。
CompareDoubles2
或CompareDoubles1
是否更快取决于您的机器和魔术常数的选择。只是测量它。您需要确保提供匹配的魔术常量,否则您将检查与不同信任区域的相等性,从而产生不同的结果。
答案 2 :(得分:1)
我认为将差异与固定容差进行比较是一个坏主意。
如果您将容差设置为1e-6,那么会发生什么,但是您比较的两个数字是 1.11e-9和1.19e-9?
这些被认为是相同的,即使它们在第二个有效数字之后不同。这可能不是你想要的。
我认为进行比较的更好方法是
equal = ( fabs(A - B) <= tol*max(fabs(A), fabs(B)) )
注意,&lt; =(而不是&lt;),因为上述内容也必须适用于0 == 0。如果设置tol = 1e-14,当它们等于14位有效数字时,两个数字将被视为相等。
旁注:如果你想测试一个数字是否为零,那么上面的测试可能并不理想,那么确实应该使用绝对阈值。
答案 3 :(得分:0)
如果您的示例中使用的舍入函数意味着舍入到第4个十进制数字,则这根本不正确。例如,如果A和B是0.000003和0.000004,它们将四舍五入为0.0,因此将被比较为相等。
通用的compairison函数不能与常量tolarance一起使用,而是与相对的一起使用。但是你在引用问题的帖子中都解释了这一点。
答案 4 :(得分:0)
没有'正确'的方法来比较浮点值(即使f == 0.0可能是正确的)。不同的比较可能是合适的。看看http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
答案 5 :(得分:0)
与其他帖子类似,但引入了比例不变性:如果你正在做一些事情,比如将两组数字加在一起,然后你想知道两个集合的数量是否相等,你可以得到日志的绝对值 - 比率(对数差)和测试,看它是否小于你的规定公差。这样,例如如果在求和计算中将所有数字乘以10或100,则不会影响答案是否相等的结果。您应该有一个单独的测试来确定两个数字是否相等,因为它们足够接近0。