比较 2 个双精度值的正确方法是什么?
What is correct way to compare 2 doubles values?
这里有很多关于这个主题的文章、博士出版物、书籍和问题,我的问题仍然很简单。
我们如何在不编写几十个 ifs 的情况下改进这个或解决方法?
假设我有 2 个双打;
double d1 = ..;
double d2 = ..;
我们可以尝试做的最天真的想法就是尝试 if(d1==d2) // baaaad!!!
,因为我们知道我们可能会在非常接近的值上出现精度不匹配而失败。
第二个天真的事情可以是if(std::abs(d1-d2) < std::numeric_limits<double>::epsilon())
对于相对较大的双打,这仍然失败,因为 std::numeric_limits<double>::epsilon()
描述如下:
Returns the machine epsilon, that is, the difference between 1.0 and the next value representable by the floating-point type T
双倍的是0.00000000000000022204
所以我想到了这个:
double epsilon = std::max(d1,d2)/1E14;
// 我可以接受第 14 位后的精度不匹配,无论数字有多大。
这里的问题是对于小数字这会失败,例如打印 0.00..00
double d = 1E-7;
std::cout<<std::fixed<<std::setprecision(20)<< d/1E14;
所以问题是是否有一个通用的 solution/workaround,或者我应该写几十个 ifs 来正确地决定我的面额,以免过度精确?
So the question will be is there a generic solution/workaround for this
不会有适用于所有用例的有限精度浮点的通用解决方案。不可能,因为每次计算的正确阈值都是特定的,一般不能自动知道。
你必须知道你在比较什么以及你期望从比较中得到什么。完整的解释不适合这个答案,但你可以从这个博客中找到大部分信息:https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/(不是我的)。
但是有一个通用的 solution/workaround side-steps 问题:使用无限精度算术。 C++标准库没有提供无限精度算术的实现。
这里有很多关于这个主题的文章、博士出版物、书籍和问题,我的问题仍然很简单。
我们如何在不编写几十个 ifs 的情况下改进这个或解决方法?
假设我有 2 个双打;
double d1 = ..;
double d2 = ..;
我们可以尝试做的最天真的想法就是尝试 if(d1==d2) // baaaad!!!
,因为我们知道我们可能会在非常接近的值上出现精度不匹配而失败。
第二个天真的事情可以是if(std::abs(d1-d2) < std::numeric_limits<double>::epsilon())
对于相对较大的双打,这仍然失败,因为 std::numeric_limits<double>::epsilon()
描述如下:
Returns the machine epsilon, that is, the difference between 1.0 and the next value representable by the floating-point type T
双倍的是0.00000000000000022204
所以我想到了这个:
double epsilon = std::max(d1,d2)/1E14;
// 我可以接受第 14 位后的精度不匹配,无论数字有多大。
这里的问题是对于小数字这会失败,例如打印 0.00..00
double d = 1E-7;
std::cout<<std::fixed<<std::setprecision(20)<< d/1E14;
所以问题是是否有一个通用的 solution/workaround,或者我应该写几十个 ifs 来正确地决定我的面额,以免过度精确?
So the question will be is there a generic solution/workaround for this
不会有适用于所有用例的有限精度浮点的通用解决方案。不可能,因为每次计算的正确阈值都是特定的,一般不能自动知道。
你必须知道你在比较什么以及你期望从比较中得到什么。完整的解释不适合这个答案,但你可以从这个博客中找到大部分信息:https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/(不是我的)。
但是有一个通用的 solution/workaround side-steps 问题:使用无限精度算术。 C++标准库没有提供无限精度算术的实现。