为什么我的双重比较失败C++

问题描述:

我正在一个项目,并完成它我需要做一些比较双,浮法... 问题是,当我比较两个双分别是最大值一张双人床和一个双+ 1的最大价值,比较失败... 我做为什么我的双重比较失败C++

if (std::max(d_max + 1.1, (d_max)) == d_max) 
    std::cout << "bad" << std::endl; 

功能最多的答案是D_MAX和“坏”显示... 是具有人想法还是解决方案,以便比较我的精确度? 我检查了谷歌,但我发现更多的解释比我的问题真正的解决方案... 非常感谢!

+6

目前还不清楚你在这里期待什么。如果'd_max'是'double'的最大值,那么你不会得到比它高的任何东西。 – 2013-02-23 14:05:52

+0

最大... – 2013-02-23 14:07:05

+0

是不是可以比较一个double的最高值与另一个没有type的值? – bottus 2013-02-23 14:07:53

C++中的所有对象都有一个类型。 d_max的类型是doubled_max + 1.1的类型仍然是双倍的。如果d_maxdouble的最大值,那么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_maxld是相等的。为什么?那么d_maxdouble。当您执行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 (也就是1后面有289个零)以实际使值的变化:

double d_max = std::numeric_limits<double>::max(); 
long double ld = d_max + 1E289L; 
std::cout << (d_max == ld) << std::endl; 

此外,也不能保证long doubledouble更精确。唯一的保证是它不具有精度较低的

+0

我明白你的意思,但即使我没有使用最大函数进行比较,我也会比较一个double值和一个long值,它们分别代表值:max双倍和最大值的双+ 1,我得到的错误比以前...这就是我不明白。如果我不犯任何错误,长双重比双倍大,不是吗? – bottus 2013-02-23 14:17:31

+0

@bottus看我的编辑。 – 2013-02-23 14:27:30

+0

@bottus - 不要认为'long double'大于'double'。核实。使用'std :: numeric_limits :: max()'。 – 2013-02-23 14:27:42

让我们假装双打表示为十进制浮点数,科学记数法。然后,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是提供最大的价值,但它是比你添加的要大得多。

+0

好吧,我很好理解你的解释;)我所做的目标是管理我的程序中的下溢和溢出。我需要做一些操作,比如*,/ ......我能做的最大操作是double的double * max值的最大值。好的。但我想管理溢出到分配。我的意思是如果我做一个像双测试= 1000000000000000的小测试;我的程序不应该崩溃,我真的不知道该怎么做......当我发现限制时,我认为它会是足够的,但它似乎不是。你知道是否可以管理吗?谢谢 – bottus 2013-02-23 14:38:48

+0

我不明白你到底想要做什么。 – leftaroundabout 2013-02-23 14:42:18

+0

我试图抓住有可能获得溢出或下溢。我的项目是在不同类型之间做一些操作。当您尝试直接在程序中为类型赋值时,编译器不会让您这样做。但我使用像float(2.324)double(5.15154)mul(用于乘法)的文件配置来完成它可能会在文件中产生荒谬的价值,编译器不会看到它,那么我需要检查之前指定是否存在欠缺或溢出;) – bottus 2013-02-23 14:49:11