比较一下 [英] Comparing doubles

查看:112
本文介绍了比较一下的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个程序,它包含一个while循环,读取两个双打并打印。该程序还打印了更大的数字和更小的数字。



这是我迄今为止的代码。

  int main()
{

//变量声明

double a;
double b;

while(a,b!='|')// WHILE A& B DO NOT EQUAL'|'
{
cin>> a>> b;
cout<< a<< b<< \\\
;


if(a< b)// IF A< B:SMALLER VALUE is A
cout< 较小的值是:< a<< endl
<< 较大的值是:< b<< endl;

else if(b< a)// ELSE IF B cout<< 较小的值是:< b<< endl
<< 较大的值是:< a<< endl;
else if(b == a)
cout<< 你输入的两个数字是相等的。 << \\\
;

}
}

下一步是让程序如果两个数字相差小于1.0 / 10000000,则写出数字几乎相等。


解决方案

这里是我如何测试平等,没有fudge因子:

  if(
//测试1:非常便宜,但可能导致假阴性
a == b ||
//测试2:更昂贵,但是综合
std :: abs(ab)< std :: abs(std :: min(a,b))* std :: numeric_limits< double& :: epsilon())
std :: cout<< 数字等于\\\
;

说明



<第一个测试是一个简单的比较。当然,我们都知道,比较双精度值可能导致它们被认为是不相等的,即使它们在逻辑上是等价的。



双精度浮点值可以容纳数字的最重要的十五位数字(实际上≈15.955 digits)。因此,如果(大约)他们的前15个数字匹配,我们想调用两个值相等。为了另一种方式,我们想要称它们相等,如果他们在彼此的一个缩放的epsilon内。这是第二个测试计算的结果。



您可以选择添加比单个缩放的epsilon更多的余地,因为更大的浮点错误迭代计算。为此,在第二个测试比较的右侧添加一个错误因子:

  double error_factor = 2.0; 

if(a == b ||
std :: abs(ab)< std :: abs(std :: min(a,b))* std :: numeric_limits& double> :: epsilon()*
error_factor)
std :: cout<< 数字等于\\\
;

我不能给你一个固定的值 error_factor ,因为它将取决于进入你的计算的错误的数量。但是,通过一些测试,您应该能够找到适合您的应用程序的合理值。请记住,添加一个基于投机的(任意)误差因素会让你回到Fudge因子领域。



摘要 / p>

您可以将以下测试包装到(n inline)函数中:

  inline bool logically_equal(double a,double b,double error_factor = 1.0)
{
return a == b ||
std :: abs(a-b)< std :: abs(std :: min(a,b))* std :: numeric_limits< double> :: epsilon()*
error_factor;
}


I'm writing a program that consists of a while loop that reads two doubles and prints them. The program also prints what the larger number is and what the smaller number is.

this is the code i have so far.

int main()
{

                                    // VARIABLE DECLARATIONS 

    double a;
    double b;

    while (a,b != '|')              //WHILE A & B DO NOT EQUAL '|'
    {
        cin >>a >>b;
        cout << a << b << "\n" ;


        if (a<b)                    //IF A<B: SMALLER VALUE IS A
        cout << "The smaller value is:" << a << endl 
             << "The larger value is:" << b << endl ;

        else if (b<a)               //ELSE IF B<A 
            cout << "The smaller value is:" << b << endl 
                 << "The larger value is:" << a << endl ;
        else if (b==a)
            cout << "The two numbers you entered are equal." << "\n" ;

    }
}

The next step is having the program write out "the numbers are almost equal" if the two numbers differ by less than 1.0/10000000. How would I do this?

解决方案

Here is how I would test for equality, without a "fudge factor":

if (
    // Test 1: Very cheap, but can result in false negatives
    a==b || 
    // Test 2: More expensive, but comprehensive
    std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon())
  std::cout << "The numbers are equal\n";

Explanation

The first test is a simple comparison. Of course we all know that comparing double precision values can result in them being deemed unequal, even when they are logically equivalent.

A double precision floating point value can hold the most significant fifteen digits of a number (actually ≈15.955 digits). Therefore, we want to call two values equal if (approximately) their first fifteen digits match. To phrase this another way, we want to call them equal if they are within one scaled epsilon of each other. This is exactly what the second test computes.

You can choose to add more leeway than a single scaled epsilon, due to more significant floating point errors creeping in as a result of iterative computation. To do this, add an error factor to the right hand side of the second test's comparison:

double error_factor=2.0;

if (a==b ||         
    std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*
                  error_factor)
  std::cout << "The numbers are equal\n";

I cannot give you a fixed value for the error_factor, since it will depend on the amount of error that creeps into your computations. However, with some testing you should be able to find a reasonable value that suits your application. Do keep in mind that adding an (arbitrary) error factor based on speculation alone will put you right back into fudge factor territory.

Summary

You can wrap the following test into a(n inline) function:

inline bool logically_equal(double a, double b, double error_factor=1.0)
{
  return a==b || 
    std::abs(a-b)<std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*
                  error_factor;
}

这篇关于比较一下的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆