我正在研究一个项目并完成它我需要与double进行一些比较,浮动...... 问题是,当我比较两个双倍时,它们分别是双倍的最大值和双倍+ 1的最大值,比较失败... 我做
if (std::max(d_max + 1.1, (d_max)) == d_max)
std::cout << "bad" << std::endl;
函数max的答案是d_max,显示“bad”... 有人有想法或解决方案来获得我的比较精确度吗? 我检查谷歌,但我发现更多的解释,而不是真正解决我的问题... 非常感谢!
答案 0 :(得分:7)
C ++中的所有对象都有一个类型。 d_max
的类型为double
。 d_max + 1.1
的类型仍然是两倍。如果d_max
是double
的最大值,则d_max + 1.1
无法表示,将使用最接近的可表示值,即d_max
(但是,如果添加值越大,最接近的可表示值被认为是正无穷大)。因此,您的std::max
来电相当于:
std::max(d_max, d_max)
演示:
double d_max = std::numeric_limits<double>::max();
bool b = (d_max == (d_max + 1.1));
std::cout << std::boolalpha << b << std::endl;
这会将true
作为输出。
在回应你的评论时,我认为你正在做这样的事情:
double d_max = std::numeric_limits<double>::max();
long double ld = d_max + 1;
std::cout << (d_max == ld) << std::endl;
奇怪的是,你发现显然d_max
和ld
是平等的。为什么?好d_max
是double
。当您执行d_max + 1
时,操作的结果也是double
- d_max + 1
的值无法在double
中表示,如前所述,所以选择最接近的可表示值(d_max
)。然后将此值分配给ld
。
请注意,只有确保运算符产生long double
(可能带有d_max + 1.0L
),才可能无法解决此问题。如此庞大的数字(大约10^308
表示IEEE 754),添加1将不会将您移动到long double
中的下一个可表示值。在我的实现中,我必须添加10个 289 (即1然后是289个零)才能实际导致值的变化:
double d_max = std::numeric_limits<double>::max();
long double ld = d_max + 1E289L;
std::cout << (d_max == ld) << std::endl;
此外,无法保证long double
的精确度高于double
。唯一的保证是它没有更少的精度。
答案 1 :(得分:1)
让我们假装双打表示为十进制浮点数,科学计数法。然后,d_max
就像
9.999999999999999999 ⋅ 10⁹⁹
现在让我们添加1.1
:
9.999999999999999999 ⋅ 10⁹⁹ + 1.1
= 999999999999999999900000000...000 + 1.1
= 999999999999999999900000000...001.1
将那个数据调整为20,甚至是40个有效数字(你必须将这些类型,甚至是长数字,只有有限的信息容量),你得到......?好吧,再次d_max
。
int main() {
long double d_max = std::numeric_limits<double>::max();
if(d_max == d_max - 1.1)
std::cout << " d_max = " << d_max
<< "\n== d_max - 1.1 = " << d_max + 1.1 << std::endl;
return 0;
}
输出
d_max = 1.79769e+308
== d_max - 1.1 = 1.79769e+308
即。这与d_max
是可用的最大值无关,但它比你添加的值大得多。