我刚用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替换为:
时,我也得到相同的resukltdouble variable1=(numeric_limits<double>::max()-10000000000000);
比较仍然表明它们是平等的。我需要减去多少才能看到它们开始有所不同?
答案 0 :(得分:10)
The maximum value for a double is 1.7976931348623157E+308。由于缺乏精确性,添加和删除小值(如50和5)实际上并不会更改变量的值。因此他们保持不变。
答案 1 :(得分:3)
double
中没有足够的精确度来区分M
和M-45
,其中M
是double
可以表示的最大值}。
想象一下,你将原子计数到最接近的百万。 “1234.56亿个原子”加上1个原子仍然是“1234.56亿个原子”,因为“百万”计数系统中没有空间可以使1个额外原子产生任何差异。
答案 2 :(得分:2)
numeric_limits<double>::max()
是 huuuuuge 号码。但是双精度的绝对值越大,其精度就越小。显然,在这种情况下,max-50
和max-5
与double
的观点无法区分。
答案 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)