Float value used as a key in a multimar

If you compare between float, I think it can’t just use equal ==, you need to check if abs (ab) <epsilon. So, when a float value is used as a key, is it possible to use the equal_range function?

eg:

std::multimap<float, string> ds; ds.insert(make_pair(2.0, string("a"))); ds.insert(make_pair(2.0, string("b"))); ds.insert(make_pair(3.0, string("d"))); ds.equal_range(2.0) 
+4
source share
4 answers

std :: multimap :: equal_range is not actually calculated using operator== at all. It is calculated only using < AND > . In fact, these are two iterators, the first of which is std :: multimap :: lower_bound (the first element is not less than the specified key), and the second is std :: multimap :: upper_bound (the first element is larger than the specified key).

Thus, it is completely safe to use with floats and doublings.

+3
source

Just check this out and you will see that it clearly works.

 #include <map> #include <string> #include <iostream> int main() { std::multimap<float, std::string> ds; ds.emplace(2.0f, std::string("a")); ds.emplace(2.0f, std::string("b")); ds.emplace(3.0f, std::string("d")); auto r = ds.equal_range(2.0f); for ( auto it = r.first; it != r.second; ++it ) std::cout << it->second << std::endl; } 

Output:

 a b 
0
source

Who says you can't use == to compare two floats? == works great for floats; it will return true if they are equal and false if they are different. (There are some weird things about NaN and negative zeros, but that doesn't apply to range checking).

Obviously, if you are looking for a value that is not equal, using == for any value on the multimap, it will not be found. And if you add two values ​​that are as close to each other as possible, they will both be added.

-one
source

You can define your own less operator for float . See the following example.

 // http://www.cplusplus.com/reference/map/multimap/ #include <map> #include <cassert> #include <iostream> #include <algorithm> class CApproxFloatLess { double m_eps; public: CApproxFloatLess(float eps) : m_eps(eps) { assert(eps >= 0); } bool operator () (float x, float y) const { return x + m_eps*(1+std::abs(x)) < y; } }; template <class It> void info(float x, It& it) { std::cout << "Found pair (" << it->first << ", " << it->second << ") for " << x << ".\n"; } int main() { typedef std::multimap<float,std::string,CApproxFloatLess> MyMap; MyMap ds(CApproxFloatLess(1e-3)); ds.insert(make_pair(2.0, std::string("a"))); ds.insert(make_pair(2.0, std::string("b"))); ds.insert(make_pair(3.0, std::string("d"))); float x=2.001; MyMap::iterator it=ds.find(x); if( it != ds.end() ) info(x,it); x=1.999; it=ds.find(x); if( it != ds.end() ) info(x,it); x=2.01; it=ds.find(x); if( it != ds.end() ) info(x,it); x=3.001; it=ds.find(x); if( it != ds.end() ) info(x,it); return 0; } 

The output of this program:

 Found pair (2, a) for 2.001. Found pair (2, a) for 1.999. Found pair (3, d) for 3.001. 
-one
source

All Articles