在多映射中用作键的浮点值
float value used as a key in multimap
如果比较浮点数,我认为不能只使用等于==,需要检查是否abs(a-b) < epsilon。那么当使用float类型的value作为key时,是否可以使用equal_range函数呢?
如:
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)
只需测试一下,您就会发现它显然有效。
#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;
}
输出:
a
b
谁说不能用==来比较两个浮点数? == 非常适合花车;如果它们相等,它将 return 为真,如果它们不同,则为假。 (关于 NaN 和负零有一些奇怪的事情,但范围检查没有涵盖)。
显然,如果您使用 == 搜索不等于多映射中任何值的值,则不会找到该值。如果你添加两个尽可能接近的值,它们都会被添加。
您可以为 float
定义自己的 less
-运算符。请参阅以下示例。
// 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;
}
这个程序的输出是:
Found pair (2, a) for 2.001.
Found pair (2, a) for 1.999.
Found pair (3, d) for 3.001.
std::multimap::equal_range is not actually calculated using operator==
at all. It is calculated using <
AND >
only. It is actually two iterators, the first being the std::multimap::lower_bound (first element not less than the given key) and the second being the std::multimap::upper_bound(第一个元素 大于 给定键)。
所以使用 floats 和 doubles.
是相当安全的
如果比较浮点数,我认为不能只使用等于==,需要检查是否abs(a-b) < epsilon。那么当使用float类型的value作为key时,是否可以使用equal_range函数呢?
如:
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)
只需测试一下,您就会发现它显然有效。
#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;
}
输出:
a
b
谁说不能用==来比较两个浮点数? == 非常适合花车;如果它们相等,它将 return 为真,如果它们不同,则为假。 (关于 NaN 和负零有一些奇怪的事情,但范围检查没有涵盖)。
显然,如果您使用 == 搜索不等于多映射中任何值的值,则不会找到该值。如果你添加两个尽可能接近的值,它们都会被添加。
您可以为 float
定义自己的 less
-运算符。请参阅以下示例。
// 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;
}
这个程序的输出是:
Found pair (2, a) for 2.001.
Found pair (2, a) for 1.999.
Found pair (3, d) for 3.001.
std::multimap::equal_range is not actually calculated using operator==
at all. It is calculated using <
AND >
only. It is actually two iterators, the first being the std::multimap::lower_bound (first element not less than the given key) and the second being the std::multimap::upper_bound(第一个元素 大于 给定键)。
所以使用 floats 和 doubles.
是相当安全的