比较双打

Cap*_*tay 11 c++

我正在编写一个由while循环组成的程序,它读取两个双打并打印它们.该程序还会打印较大的数字和较小的数字.

这是我到目前为止的代码.

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" ;

    }
}
Run Code Online (Sandbox Code Playgroud)

如果两个数字相差小于1.0/10000000,则下一步是让程序写出"数字几乎相等".我该怎么做?

Mic*_*eyn 25

这是我如何测试平等,没有"软糖因素":

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";
Run Code Online (Sandbox Code Playgroud)

说明

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

双精度浮点值可以保存一个数字的最重要的十五位数(实际≈15.955位数).因此,如果(大约)它们的前十五个数字匹配,我们想要调用两个值相等.换句话说,如果它们在彼此的一个缩放的epsilon内,我们希望将它们称为相等.这正是第二次测试计算的内容.

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

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";
Run Code Online (Sandbox Code Playgroud)

我不能给你一个固定值的error_factor,因为这将取决于错误的所爬的到您的计算量.但是,通过一些测试,您应该能够找到适合您应用的合理值.千万记住,添加仅基于猜测的(任意)误差因素将让你右后卫蒙混因素领土.

摘要

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @Mihai,它与double可以表示的最大整数位数有关,即十五.因此,如果减法结果的绝对值小于减法可能由于不精确的表示而产生的最小值,则调用原始数字不相等. (2认同)

Bil*_*eal 11

std::abs(a - b) < 0.000001

当然,用你认为"差不多"的东西替换常量.

  • 另请注意,"错误"会随着a和b的大小而增大. (2认同)