C++ 是否有一种通用的标准方法来存储std::set和/或std::unordered_集合中的浮点?
我们知道,楠!=IEEE浮点数的NaN。因此,许多对浮点数的“明显”操作都有一个隐藏的陷阱,数据中的nan会把事情搞得一团糟。例如:C++ 是否有一种通用的标准方法来存储std::set和/或std::unordered_集合中的浮点?,c++,stl,floating-point,nan,C++,Stl,Floating Point,Nan,我们知道,楠!=IEEE浮点数的NaN。因此,许多对浮点数的“明显”操作都有一个隐藏的陷阱,数据中的nan会把事情搞得一团糟。例如: 显而易见的方法是这样的: template <typename T> struct NaNSafeEqual0 { bool operator()(const T& a, const T& b) const { if (!(a == a) || !(b == b)) { retur
template <typename T>
struct NaNSafeEqual0 {
bool operator()(const T& a, const T& b) const {
if (!(a == a) || !(b == b)) {
return (a == a) == (b == b); // <- Still has a gotcha: see below.
}
return a == b; // This deals with 0.0 == -0.0;
}
};
那么:是否有一种通用的标准方法来编写less
和equal
,允许在std::set和/或std::unordered_set中安全存储浮点数?如果没有,Boost或其他广泛使用的库是否提供了一个?当我说“通用”时,我的意思是,如果有一个标准的NaNSafeEqual
,那么我可以将其专门化为VecND
类型,所以我可以让VecND::operator==
具有典型的NaN行为,但我可以提供一个专门的NaNSafeEqual
,对于两个按位相同的NaN向量,它的计算结果为true
。当我说“generic”时,我的意思是,如果有一个标准的NaNSafeEqual
,那么我可以将其专门化为VecND
类型,因此我可以使VecND::operator==
具有典型的NaN行为,但我可以提供专门的NaNSafeEqual
,对于两个按位相同的NaN向量,它的计算结果将为true
。
template <typename T>
struct NaNSafeEqual {
std::size_t operator()(const T& a, const T& b) const {
if (a == a || b == b) {
return a == b; // At least one isn't nan.
}
static_assert(sizeof(T) <= sizeof(std::size_t));
union {
T data;
std::size_t s;
} ua, ub;
ua.s = 0;
ub.s = 0;
ua.data = a;
ub.data = b;
return ua.s == ub.s;
}
};