我想检查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();
}
}