为了账号安全,请及时绑定邮箱和手机立即绑定

std:map中的浮点键

std:map中的浮点键

C++
慕哥9229398 2019-12-03 14:38:12
以下代码应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<(...)才能实现此功能?
查看完整描述

3 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

您可以实现自己的比较功能。


#include <functional>


class own_double_less : public std::binary_function<double,double,bool>

{

public:

  own_double_less( double arg_ = 1e-7 ) : epsilon(arg_) {}

  bool operator()( const double &left, const double &right  ) const

  {

    // you can choose other way to make decision

    // (The original version is: return left < right;) 

    return (abs(left - right) > epsilon) && (left < right);

  }

  double epsilon;

};

// your map:

map<double,double,own_double_less> mymap;


查看完整回答
反对 回复 2019-12-03
?
慕容森

TA贡献1853条经验 获得超18个赞

这是使用软比较(又称epsilon或几乎相等)如何导致问题的简化示例。


让我们epsilon = 2为简单起见。把1和4到您map。现在看起来像这样:


1

 \

  4

所以,1是树的根。


现在,摆在数2,3,4的顺序。每个都将替换根,因为它与根相等。所以你有


4

 \

  4

已经坏了 (假设没有试图重新平衡树而成。)我们可以跟上去5,6,7:


7

 \

  4

甚至更糟,因为现在如果我们询问是否4在其中,它会说“ no”,并且如果我们要求一个小于的值的迭代器7,则不会包含4。


尽管我必须说,我过去曾map多次使用基于此模糊比较运算符的s,而且每当我发现一个bug时,都不会因此而来。这是因为我的应用程序区域中的数据集实际上从不构成压力测试此问题的方法。


查看完整回答
反对 回复 2019-12-03
  • 3 回答
  • 0 关注
  • 908 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信