the function evaluates the answer indefinitely

Рейтинг: -1Ответов: 1Опубликовано: 06.02.2023

there is a cubic equation, you need to find only 1 of its root. first, using the difference in signs, I find the gap where the root will be, then I find it with a binary search. coefficients can only be between -1000 and 1000 inclusive. the problem is that my code solves some equations calmly, and in some it goes into an infinite loop, although I found an approximate answer through for ((for example) 100) and it converged with the answer on any site that solves equations

#include <iostream>
#include <cmath>
using namespace std;

int a, b, c, d;
// -1, -1, -1, -1 -- work
// -1, -10, -20, -30 -- dont work

double func(double x) {
    return (a)*pow(x, 3) + (b)*pow(x, 2) + (c)*x + (d);
}

int getSing(double n) {
    if (n > 0) {
        return 1;
    } else if (n < 0) {
        return -1;
    } else {
        return 0;
    }
}

int main()
{
    cin >> a >> b >> c >> d;

    int left = -1000;
    int step = 10;
    int right = left + step;
    int sing = getSing(func(right));
    int opposite_sing = -sing;
    int mid = 1;

    while (sing != opposite_sing) {
        left += step;
        right = left + step;
        sing = getSing(func(right));
    }

    while (func(mid) != 0) {
        mid = (left + right) / 2;
        if (func(mid) > 0) {
            left = mid;
        } else {
            right = mid;
        }
    }

    cout << mid;
}

Ответы

▲ 2

Используйте типы с плавающей точкой. Никто же не гарантирует, что у вас будут только целые корни, или что right+left всегда будет четным :)

#include <iostream>
#include <cmath>
using namespace std;

// -1, -1, -1, -1 -- work
// -1, -10, -20, -30 -- dont work

double func(double x, double a, double b, double c, double d)
{
    return ((a*x+b)*x+c)*x+d;
}

int main()
{
    double a,b,c,d, eps = 1e-10;
    cin >> a >> b >> c >> d;

    double left = -1e6, right = 1e6; // Чтоб с запасом :)

    double fl = func(left,a,b,c,d), fr = func(right,a,b,c,d);

    if (fl*fr > 0)
    {
        cout << "Wrong range\n";
        return 0;
    }

    while(right - left > eps)
    {
        double x = (left+right)/2;
        double f = func(x,a,b,c,d);
        if (f*fl < 0)
        {
            right = x;
        }
        else
        {
            left = x;
        }
    }
    cout << (left+right)/2 << endl;
}

Кстати, посмотрите на досуге, что такое схема Горнера...