Метод деления пополам - разрыв цикла - PullRequest
0 голосов
/ 29 марта 2019

Проблемы с выходом из цикла while после того, как был найден правильный корень (значение r3 == 0).Должен ли я где-то использовать перерыв, если да, то где?

Я уже пытался поиграться с условными операторами if, else if и else.Пытался разместить перерыв;в разных местах, но не смог получить его таким образом, чтобы я все еще получал правильный вывод (в основном он ломался после первой итерации)

float fun(float t);
float fun(float t)
{
    double result; 
    result = (cos(t) - t); //my function
    return result; 
}

void main()
{
    float a; float b; float error; float root;
    scanf("%f %f %f", &a, &b, &error); //scanning for range of bisection and maximum allowed error
int i = 0; 

if (fun(a) == 0)
{
    root = a; 
    printf("The root is : %f", a);
}
else if (fun(b) == 0)
{
    root = b; 
    printf("The root is : %f", b);
}
else 
{
    while (i < 100)
    {
        float r1 = fun(a);
        float r2 = fun(b);
        root = (a+b)/2.0; 
        float r3 = fun(root); 
        printf("The root after %d iteration is %f\n",i,root);
        if(r1*r3 < 0 && r3 != 0) //intermediate value theorem
        {
            b = root;
        }
        else if(r3*r2 < 0 && r3 != 0) //intermediate value theorem
            {
                a = root;
            }
        i++;
        int *p = &i; //not necessary at this moment
    }
}
printf("The approximation to the root is %f",root);

Ожидаемый результат - программа должна завершиться при первойвремя, когда r3 == 0, поскольку найденный корень, использующий метод деления пополам, правильный.Поэтому последней итерацией должна быть та, которая имеет правильное конечное значение для корня ...

1 Ответ

1 голос
/ 29 марта 2019

Первым делом, условие r1 * r3 < 0 подразумевает, что r3 != 0 (если r3 == 0, то продукт также равен 0);нет необходимости проверять это.

Во-вторых, очень маловероятно, что числа с плавающей точкой будут равны чему-либо, включая 0. Вы должны запускать цикл, если вы не удовлетворены результатом.Параметр error указан по причине.

В-третьих, неудачный выбор a и b может никогда не дать вам результата: если fun(a), fun(b), fun((a+b)/2) все имеют одинаковый знак, ни a ни b никогда не меняется.

Тем не менее, правильный код должен выглядеть следующим образом:

    if (fun(a) * fun(b) > 0) {
        bail_out("Root may not exist\n");
    }

    while (b - a > error) /* see note below */ {
        mid = a + (b - a)/2;
        if (fun(a) * fun(mid) > 0) {
            a = mid;
        } else {
            b = mid;
        }
    }

Примечание. Указанное выше условие зависит от семантики ошибки.В определенных обстоятельствах (abs(fun(mid)) > error) может быть предпочтительным.

...