0


我试图用 C++ 帮助解决下一个方程: 3sin(sqrt(x)) + 0.35x - 3.8 = 0 有解
的区域是 [2, 3]

我写了下一个代码:

float f(float x)
{
    return (3 * sin(sqrt(x))) + (0.35 * x) - 3.8; //this is equation i am trying to solve
}

float g(float x, float(*f_ptr)(float)) 
{
    const float CONST = 0.1f; //const used to solve equation

    return CONST * f_ptr(x) + x;
}

void Task4_CalculateSomething()
{
    float x0, //starting aproximation
        xk, //current aproximation
        a = 2, //left barrier
        b = 3, //right barrier
        epsilon = 0.001; //allowed error

    const float REAL_SOLUTION = 2.2985; //real solution of selected equation

    printf("Setup starting aproximation: ");
    scanf("%f", &x0);

    do
    {
        xk = g(x0, f); //calc current aproximation

        if (fabs(xk - x0) < epsilon) //if Xn - Xn-1 fits the allowed error, the solution must be found
            break; //then we exit
        else
            x0 = xk; //else reset x values
    }
    while (fabs(a - x0) > epsilon && fabs(b - x0) > epsilon);

    printf("Found solution: %f\nReal solution: %f\n", xk, REAL_SOLUTION);
}

但它给了我奇怪的结果,比如 -1.#IND00,我什至不知道它是什么。
而且我在那里找不到任何错误...

4

2 回答 2

3

在高层次上,正在发生的事情是:

  1. 您的算法无法正常工作。
  2. 在某个迭代中,xk变为负数。
  3. 当它传递给 时sqrt,将返回一个 NaN。
  4. 迭代终止。
  5. 调用printf显示NaN-1.#IND00

您可以使用调试器识别所有这些,甚至可以使用老式的技术来输入一些调试printf输出。例如,添加一些代码以xk在循环的每次迭代中打印。

由于您知道解决方案在于 [2,3],因此我个人会使用包围式根查找器。例如,二分法

于 2012-05-20T19:00:17.210 回答
1

尝试使用像这样的另一种算法:

  1. 写出函数的导数:der=1.5*cos(sqrt((x))/sqrt(x)+.35
  2. 下一个值是 xk=x0-mysinc(x0)/der(x0)

在几个步骤中将落入解决方案...或使您的变量 CONST 具有-1/der(x) 的动态值。

于 2012-05-20T21:03:06.457 回答