К оглавлению

Решение уравнения 3-й, 4-й и 5-й степеней на C++

С.И.Хашин

C++-модуль

Модуль состоит из двух файлов, poly34.h, poly34.cpp.
Для его работы не требуются никакие дополнительные библиотеки.
Из стандартных include-файлов подключается только math.h.
Динамическое выделение памяти также не используется.

poly34.h - заголовочный файл
poly34.cpp - реализация.

Уравнения степени 3

Линейные и квадратные уравнения с действительными коэффициентами решаются просто. Для решения кубических уравнений можно взять триногометрическую формулу Виета, код программы занимает около двух десятков строк. Корни уравнения

x3 + ax2 + bx + c = 0
находятся с помощью функции
int   SolveP3(double *x,double a,double b,double c);
Здесь x должен быть маccивом длины 3.

В случае трех действительных корней функция возвращает число 3, сами корни возвращаются в x[0],x[1],x[2].

Замечание 1. Корни не обязательно упорядочены!
Если два корня совпадают, то функция возвращает число 2, а в массиве x по-прежнему лежат три числа.

Если функция возвращает 1, то x[0] - действительный корень и x[1]±i*x[2] - пара комплексно сопряженных.

Замечание 2. Из-за погрешностей округления пара комплексно сопряженных корней с очень малой мнимой частью иногда может оказаться действительным корнем кратности 2. Например, для уравнения x3 - 5x2 + 8x - 4 = 0 с корнями 1,2,2 получаются корни     1.0, 2.0±i*9.6e-17. Если мнимая часть корня по модулю не превышает 1e-14, то функция SolveP3 сама заменяет такую пару на один действительный двукратный корень, но пользователь должен все равно иметь в виду возможность такой ситуации.

Уравнения степени 4

Для решения уравнений 4-й степени лучше взять решение Декарта — Эйлера. Корни уравнения

x4 + ax3 + bx2 + cx + d = 0
находятся с помощью функции
int   SolveP4(double *x,double a,double b,double c,double d);
Здесь x должен быть маccивом длины 4.

В случае 4-х действительных корней функция возвращает число 4, сами корни возвращаются в x[0],x[1],x[2],x[3].

В случае 2-х действительных и пары комплексно сопряженных корней функция возвращает число 2, x[0],x[1] - действительные корни и x[2]±i*x[3] - пара комплексно сопряженных.

Если уравнение имеет две пары пары комплексно сопряженных корней, то функция возвращает 0, x[0]±i*x[1] и x[2]±i*x[3] - сами корни.
Замечание 3. Численные эксперименты показывают, что в отдельных случаях получающаяся погрешность, довольно велика, до 10-12. Поэтому в конце найденные действительные корни уточняются с помощью одного шага метода Ньютона.
Например, для уравнения x*(x-1)*(x-0.0001)*(x-0.0002) без уточнения погрешность будет порядка 0.25*10-9, с уточнением порядка 10-16.

Уравнения степени 5

Все корни уравнения 5-й степени

f(x) = x5 + ax4 + bx3 + cx2 + dx + e = 0
не превосходят по модулю величины
brd = 1 + max( |a|, |b|, |c|, |d|, |e| ).

Уравнение 5-й степени всегда имеет по крайней мере один действительный корень. Для его нахождения, начиная с интервала [-brd,brd] сделаем 6 "делений отрезка пополам". После этого уточним корень методом Ньютона.

Найдя один действительный корень x0, поделим на него исходный многочлен f(x) и найдем корни полученного многочлена 4-й степени.

Корни многочлена f(x) находятся с помощью функции

int   SolveP5(double *x,double a,double b,double c,double d, double e);
Здесь x должен быть маccивом длины 5.

В случае 5 действительных корней функция возвращает число 5, сами корни возвращаются в x[0],x[1],x[2],x[3],x[4].

В случае 3-х действительных и пары комплексно сопряженных корней функция возвращает число 3, x[0],x[1],x[2] - действительные корни и x[3]±i*x[4] - пара комплексно сопряженных.

Если уравнение имеет две пары пары комплексно сопряженных корней, то функция возвращает 1, x[0] - действительный корень и x[1]±i*x[2] , x[3]±i*x[4] - комплексные корни.

Вспомогательные функции

Решение кубических уравнений производится в одной-единственной функции SolveP3. Для решения уравнений 4-й степени используются три вспомогательных функции:

void  CSqrt( double x, double y, double &a, double &b);  // returns as a+i*s,  sqrt(x+i*y)
int   SolveP4Bi(double *x, double b, double d);	         // solve equation x^4 + b*x^2 + d = 0
int   SolveP4De(double *x, double b, double c, double d);// solve equation x^4 + b*x^2 + c*x + d = 0
double N4Step(double x, double a,double b,double c,double d);
     // one Newton step for x^4 + a*x^3 + b*x^2 + c*x + d

Первая служит для извлечения квадратного корня из комплексного числа: a+i*s = sqrt(x+i*y).

Вторая - для решения биквадратного уравнения, третья - для решения неполного уравнения.
Замечание 4. Как и в случае кубических уравнений, корень кратности 2 или пара очень близких действительных корней может быть показана в виде пары комплексно сопряженных корней с малой мнимой частью.

Для решения уравнений 5-й степени используются функции:

double SolveP5_1(double a,double b,double c,double d,double e);
    // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0

К оглавлению


free counters