【发布时间】:2019-11-18 09:52:20
【问题描述】:
我一直有比较 double 值是否相等的问题。有一些类似fuzzy_compare(double a, double b) 的功能,但我经常没能及时找到它们。所以我想为比较运算符构建一个双精度包装类:
typedef union {
uint64_t i;
double d;
} number64;
bool Double::operator==(const double value) const {
number64 a, b;
a.d = this->value;
b.d = value;
if ((a.i & 0x8000000000000000) != (b.i & 0x8000000000000000)) {
if ((a.i & 0x7FFFFFFFFFFFFFFF) == 0 && (b.i & 0x7FFFFFFFFFFFFFFF) == 0)
return true;
return false;
}
if ((a.i & 0x7FF0000000000000) != (b.i & 0x7FF0000000000000))
return false;
uint64_t diff = (a.i & 0x000FFFFFFFFFFFF) - (b.i & 0x000FFFFFFFFFFFF) & 0x000FFFFFFFFFFFF;
return diff < 2; // 2 here is kind of some epsilon, but integer and independent of value range
}
其背后的理念是: 首先,比较符号。如果不同,则数字不同。除非所有其他位都为零。即比较 +0.0 和 -0.0,应该相等。接下来,比较指数。如果这些不同,则数字不同。最后,比较尾数。如果差异足够小,则值相等。
它似乎有效,但可以肯定的是,我想要同行评审。很可能是我忽略了一些东西。
是的,这个包装类需要所有运算符重载的东西。我跳过了,因为它们都是微不足道的。相等运算符是这个包装类的主要用途。
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
标签: c++ floating-point