std:map中的浮点键

以下代码应3.0在std::map存在的密钥中找到密钥。但是由于浮点精度,将无法找到它。


map<double, double> mymap;

mymap[3.0] = 1.0;


double t = 0.0;

for(int i = 0; i < 31; i++)

{

  t += 0.1;

  bool contains = (mymap.count(t) > 0);

}

在上面的示例中,contains将始终为false。我当前的解决方法是乘以t0.1而不是加0.1,如下所示:


for(int i = 0; i < 31; i++)

{

  t = 0.1 * i;

  bool contains = (mymap.count(t) > 0);

}

现在的问题是:


std::map如果我使用double键,是否可以将FuzzyCompare引入?浮点数比较的常见解决方案通常是a-b < epsilon。但是我看不到使用来实现此目的的简单方法std::map。我是否真的必须将double类型封装在类中并重写operator<(...)才能实现此功能?


慕哥9229398
浏览 909回答 3
3回答

长风秋雁

您可以实现自己的比较功能。#include <functional>class own_double_less : public std::binary_function<double,double,bool>{public:&nbsp; own_double_less( double arg_ = 1e-7 ) : epsilon(arg_) {}&nbsp; bool operator()( const double &left, const double &right&nbsp; ) const&nbsp; {&nbsp; &nbsp; // you can choose other way to make decision&nbsp; &nbsp; // (The original version is: return left < right;)&nbsp;&nbsp; &nbsp; return (abs(left - right) > epsilon) && (left < right);&nbsp; }&nbsp; double epsilon;};// your map:map<double,double,own_double_less> mymap;

慕容森

这是使用软比较(又称epsilon或几乎相等)如何导致问题的简化示例。让我们epsilon = 2为简单起见。把1和4到您map。现在看起来像这样:1&nbsp;\&nbsp; 4所以,1是树的根。现在,摆在数2,3,4的顺序。每个都将替换根,因为它与根相等。所以你有4&nbsp;\&nbsp; 4已经坏了 (假设没有试图重新平衡树而成。)我们可以跟上去5,6,7:7&nbsp;\&nbsp; 4甚至更糟,因为现在如果我们询问是否4在其中,它会说“ no”,并且如果我们要求一个小于的值的迭代器7,则不会包含4。尽管我必须说,我过去曾map多次使用基于此模糊比较运算符的s,而且每当我发现一个bug时,都不会因此而来。这是因为我的应用程序区域中的数据集实际上从不构成压力测试此问题的方法。
打开App,查看更多内容
随时随地看视频慕课网APP