即使它们不是,c ++中的双变量也是相等的

时间:2011-08-04 12:51:46

标签: c++ c

我刚用C ++编写了以下代码:

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

cout语句的答案出来1,即使变量2和变量1不相等。有人帮我这个吗?为什么会这样?

我知道不精确的浮点数学的概念,但不认为直接比较两个双打会发生这种情况。当我将variable1替换为:

时,我也得到相同的resuklt
double variable1=(numeric_limits<double>::max()-10000000000000);

比较仍然表明它们是平等的。我需要减去多少才能看到它们开始有所不同?

6 个答案:

答案 0 :(得分:10)

The maximum value for a double is 1.7976931348623157E+308。由于缺乏精确性,添加和删除小值(如50和5)实际上并不会更改变量的值。因此他们保持不变。

答案 1 :(得分:3)

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

想象一下,你将原子计数到最接近的百万。 “1234.56亿个原子”加上1个原子仍然是“1234.56亿个原子”,因为“百万”计数系统中没有空间可以使1个额外原子产生任何差异。

答案 2 :(得分:2)

numeric_limits<double>::max()

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

答案 3 :(得分:0)

您应该阅读floating point comparison guide。简而言之,这里有一些例子:

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的回答。

以下是一些额外的研究资源。

答案 4 :(得分:0)

来自C ++ 03标准:

  

3.9.1 / [...]浮点类型的值表示是   实现定义

  

5 / [...]如果在评估表达式时,结果不是   在数学上定义或不在可表示值的范围内   它的类型,行为是未定义的,除非这样的表达式是一个   常量表达式(5.19),在这种情况下程序是不正确的。

  

18.2.1.2.4 /(约numeric_limits<T>::max())最大有限值。

这意味着一旦向std::numeric_limits<T>::max()添加内容,如果T是浮点,则程序的行为是实现定义的,如果T是无符号类型则完美定义,并且未定义否则。

如果您碰巧有std::numeric_limits<T>::is_iec559 == true,在这种情况下,行为是由IEEE 754定义的。我没有它的便利,所以我无法判断variable1在这种情况下是有限的还是无限的。似乎(根据互联网上关于IEEE 754的一些讲义)它depends on the rounding mode ..

答案 5 :(得分:-1)