检查最低和最高值double

时间:2019-11-17 17:32:07

标签: c++ math double comparison

我想检查double是否在最大值处,而另一个在其最小值处。 为什么这不会在findRoot()函数中引发异常? 该程序的目标是通过二等分法找到严格单调函数的根(假设只有一个根,则仅减小或增大),但我想避免以下情况: -有一个根,但超出double的范围,因此我们无法计算出 -没有根,因此我们将移动到最大/最小两倍并抛出异常 我的函数也对-std :: pow(2,x)+ 6有效吗?对于较长的负范围它非常接近6,因此f(x)长时间给出6,这就是为什么我实现了如果A值和B值相同则改变两个范围的原因。 您还有其他建议来进行双重/浮动比较吗?

#include <iostream>
#include <cmath>

double f(double x) 
{
    //double y = -std::pow(2, x) + 6;
    //double y = -x + 100000;
    double y = 2;
    return y;
}

bool isIncreasing(double aFuncVal, double bFuncVal)
{
    return aFuncVal < bFuncVal;
}

bool isDecreasing(double aFuncVal, double bFuncVal)
{
    return aFuncVal > bFuncVal;
}


bool areBothFuncValuesPositive(double aFuncVal, double bFuncVal)
{
    return (aFuncVal > 0 && bFuncVal > 0);
}

void moveLeft(double &a, double &b)
{
    const double diff = std::fabs(a)+std::fabs(b);
    b = a;
    a = a - diff*2;
}

void moveRight(double& a, double& b)
{
    const double diff = std::fabs(a) + std::fabs(b);
    a = b;
    b = b + diff*2;
}

void moveBoth(double& a, double& b)
{
    const double diff = std::fabs(a) + std::fabs(b);
    a = a - diff * 2;
    b = b + diff * 2;
}

void changeRanges(double &a, double &b) 
{
    double aFunctionValue = f(a);
    double bFunctionValue = f(b);

    if (isIncreasing(aFunctionValue, bFunctionValue))
    {
        if (areBothFuncValuesPositive(aFunctionValue, bFunctionValue))
        {
            moveLeft(a, b);
        }
        else
        {
            moveRight(a, b);
        }
    }
    else if (isDecreasing(aFunctionValue, bFunctionValue))
    {
        if (areBothFuncValuesPositive(aFunctionValue, bFunctionValue))
        {
            moveRight(a, b);
        }
        else
        {
            moveLeft(a, b);
        }
    }
    else
    {
        moveBoth(a, b);
    }

}

double findRoot(double a, double b, double epsilon)
{
    if (a > b) std::swap(a, b);
    if (a == b) throw std::exception("Range must be higher than zero!");
    //
    if (std::fabs(f(a)) < epsilon) return a;
    if (std::fabs(f(b)) < epsilon) return b;

    while (f(a) * f(b) > 0)
    {
        if (a == -DBL_MAX && b == DBL_MAX) throw std::exception("Max scope of double reached");
        changeRanges(a, b);
    }
    if (std::fabs(f(a)) < epsilon) return a;
    if (std::fabs(f(b)) < epsilon) return b;

    double c;
    do
    {
        c = (a + b) / 2;
        if (f(a) * f(c) > 0) a = c;
        else b = c;
    } while (!(std::fabs(f(c)) < epsilon));
    return c;
}

int main()
{
    try 
    {
        std::cout << findRoot(DBL_MIN, DBL_MAX, 0.000000000001) << std::endl;
        std::cout << findRoot(100, 300, 0.00000000001) << std::endl;
        std::cout << findRoot(-3, -1, 0.00000000001)   << std::endl;
        std::cout << findRoot(300, 100, 0.00000000001) << std::endl;

        std::cout << findRoot(-100, 300, 0.00000000001) << std::endl;
        std::cout << findRoot(100, -300, 0.00000000001) << std::endl;
        std::cout << findRoot(300, -100, 0.00000000001) << std::endl;
        std::cout << findRoot(-300, 100, 0.00000000001) << std::endl;
    }
    catch (const std::exception & e)
    {
        std::cout << e.what();
    }
}

0 个答案:

没有答案