c++中的双变量即使不相等也会显示相等

double variables in c++ are showing equal even when they are not

本文关键字:显示 不相等 变量 c++      更新时间:2023-10-16

我刚刚用c++写了下面的代码:

double variable1;
double variable2;
variable1=numeric_limits<double>::max()-50;
variable2=variable1;
variable1=variable1+5;
cout<<"nVariable1==Variable2 ? "<<(variable1==variable2);

cout语句的答案是1,即使variable2和variable1不相等。有人能帮我一下吗?为什么会发生这种情况?

我知道不精确浮点数学的概念,但不认为直接比较两个双精度数会发生这种情况。另外,当我用:

替换variable1时,我也得到了相同的结果
double variable1=(numeric_limits<double>::max()-10000000000000);

比较仍然显示它们是相等的。我要减去多少才能看到它们开始不同?

双精度类型的最大值是1.7976931348623157E+308。由于缺乏精度,添加和删除像50和5这样的小值实际上并不会改变变量的值。因此它们保持不变。

double中没有足够的精度来区分MM-45,其中Mdouble所能表示的最大值。

想象一下你正在数原子到最接近的百万。"123456万个原子"加1个原子仍然是"123456万个原子",因为在"百万"计数系统中没有空间容纳额外的1个原子。

numeric_limits<double>::max()

huuuuuge号码。但是,双精度型的绝对值越大,其精度就越小。显然,在这种情况下,max-50max-5double的角度来看是无法区分的。

您应该阅读浮点数比较指南。总之,这里有一些例子:

float a = 0.15 + 0.15
float b = 0.1 + 0.2
if(a == b) // can be false!
if(a >= b) // can also be false!

与epsilon值的比较是大多数人所做的。

#define EPSILON 0.00000001
bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}

在你的例子中,这个最大值真的很大。加或减50没有任何作用。由于数字的大小,它们看起来是一样的。请看@RichieHindle的回答

这里有一些额外的研究资源。

  • 查看此博客文章
  • 还有,关于这个话题有一个堆栈溢出问题(语言无关的)。

来自c++ 03标准:

3.9.1/[…浮点类型的值表示为实现定义的

5/[…如果在表达式求值期间,结果不是在数学上定义的或不在可表示值范围内的它的类型,行为是未定义的,除非这样的表达式是常量表达式(5.19),在这种情况下程序是病态的。

18.2.1.2.4/(about numeric_limits<T>::max()) Maximum finite value.

这意味着一旦向std::numeric_limits<T>::max()添加了一些东西,如果T是浮点数,则程序的行为是实现定义的,如果T是无符号类型,则完全定义,否则未定义。

如果你碰巧有std::numeric_limits<T>::is_iec559 == true,在这种情况下,行为是由IEEE 754定义的。我手边没有,所以在这种情况下我无法判断variable1是有限的还是无限的。似乎(根据互联网上IEEE 754的一些讲义)它取决于舍入模式。

请阅读《每个计算机科学家都应该知道的浮点算术》