Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek

©2026 mgr Jerzy Wałaszek

obrazek

Równania

Równanie czwartego stopnia

SPIS TREŚCI REMANENT
Podrozdziały
 

Algorytm nr 1

Równanie czwartego stopnia (ang. quartic equation) zbudowane jest z wielomianu czwartego stopnia:

Współczynniki a, b, c, d i e są liczbami rzeczywistymi.

Im wyższy stopień wielomianu, tym bardziej skomplikowane wzory opisują jego rozwiązania. Równanie stopnia czwartego jest ostatnim, które można rozwiązać algebraicznie. Udowodniono, że równania powyżej stopnia czwartego nie posiadają ogólnej metody rozwiązywania, co nie oznacza braku pierwiastków. Równania takie, oprócz przypadków szczególnych, rozwiązuje się przy pomocy metod przybliżonych.

Rozwiązania równań czwartego stopnia matematycy opracowali dopiero w XVI wieku. Powstało wiele metod rozwiązywania tych równań. Tutaj opiszemy tylko kilka najbardziej znanych.

Na początek zajmiemy się szczególnymi przypadkami równania czwartego stopnia, które stosunkowo łatwo rozwiązać (wykorzystując poznane wcześniej metody rozwiązywania równań wielomianowych).

Równanie dwukwadratowe (ang. biquadratic equation) ma postać:

Dokonujemy podstawienia:

Otrzymaliśmy równanie kwadratowe ze zmienną y. Rozwiązujemy je i otrzymujemy dwa pierwiastki: y1 i y2. Następnie otrzymujemy pierwiastki równania dwukwadratowego:

Jeśli któryś z pierwiastków y1 lub y2 jest ujemny lub zespolony, to otrzymamy w wyniku zespolone pierwiastki xi. Jeśli interesują nas tylko rozwiązania rzeczywiste, pomijamy rozwiązania zespolone. Możemy również wykonać rachunki na liczbach zespolonych i pomijać części urojone równe zero, otrzymując w ten sposób pierwiastki rzeczywiste (każda liczba rzeczywista ma część urojoną równą zero).

Załóżmy, że mamy liczbę zespoloną o postaci:

Pierwiastek zespolony tej liczby obliczymy ze wzoru:

Część rzeczywista pierwiastka zespolonego jest zawsze nieujemna. Znak części urojonej jest taki sam jak znak części urojonej pierwiastkowanej liczby (funkcja sgn(x) ma wartość -1 dla argumentów ujemnych, 0 dla argumentu 0 i 1 dla argumentu dodatniego).

Powyższy wzór pozwala nam rozwiązać dowolne równanie dwukwadratowe za pomocą metody rozwiązywania równań kwadratowych bez rozważania różnych przypadków.

Przykładowy program rozwiązuje dowolne równanie dwukwadratowe.

C++
// Równanie czwartego stopnia
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0046
//---------------------------

#include <iostream>
#include <windows.h>
#include <cmath>
#include <iomanip>

using namespace std;

// Tutaj definiujemy
// dane wejściowe
//------------------

// Dokładność porównania
// z zerem
double epsy = 1e-12;

// Definicja typu zespolonego
struct cmplx
{
  double re, im;
};

// Wyświetla + przed
// liczbą dodatnią,
// '-' przed ujemną
//------------------
void pl(double x)
{
  if(x >= 0)
    cout << '+';
  else
    cout << '-';
  cout << fabs(x);
}

// Funkcja wylicza
// pierwiastek zespolony
//----------------------
void csqrt(cmplx y, cmplx & x)
{
  double a,b;
  a = y.re;
  b = y.im;
  double c = sqrt(a*a+b*b);
  x.re = sqrt((c+a)/2.0);
  x.im = sqrt((c-a)/2.0);
  if(b < 0)
    x.im = - x.im;
}

// Funkcja wyświetlająca
// liczbę zespoloną
//----------------------
void cmplxprint(cmplx x)
{
  // Część rzeczywistą
  // wyświetlamy zawsze
  pl(x.re);
  // Jeśli część urojona
  // jest różna od zera,
  // to ją wyświetlamy
  if(fabs(x.im) > epsy)
  {
    pl(x.im);
    cout << "i";
  }
  cout << endl;
}

// Funkcja rozwiązująca
// równanie dwukwadratowe
// a,b,c - współczynniki
// wielomianu
//-----------------------
void be(double a, double b, double c)
{
  cout << "\nRównanie: ";
  pl(a);
  cout << "*x^4";
  pl(b);
  cout << "*x^2";
  pl(c);
  cout << " = 0\n";

  double delta;
  cmplx y1,y2,x1,x2,x3,x4;

  // Zerujemy części
  // urojone zmiennych
  y1.im = 0.0;
  y2.im = 0.0;
  x1.im = 0.0;
  x2.im = 0.0;
  x3.im = 0.0;
  x4.im = 0.0;

  // Obliczamy wyróżnik
  delta = b*b-4.0*a*c;

  // Jeśli wyróżnik jest nieujemny,
  // wyliczamy pierwiastki rzeczywiste
  if(fabs(delta) < epsy)
  {
    y1.re = -b/2.0/a;
    y2.re = y1.re;
  }
  else if(delta > 0)
  {
    delta = sqrt(delta);
    y1.re = (-b-delta)/2.0/a;
    y2.re = (-b+delta)/2.0/a;
  }
  else
  { // Inaczej wyliczamy
    // pierwiastki zespolone
    delta = sqrt(-delta);
    y1.re = -b/2.0/a;
    y2.re = y1.re;
    y1.im = -delta/2.0/a;
    y2.im =  delta/2.0/a;
  }

  // Obliczamy pierwiastki
  // zespolone rozwiązań
  // równania kwadratowego
  csqrt(y1,x1);
  x1.re = -x1.re;
  x1.im = -x1.im; // Ten jest ujemny
  csqrt(y1,x2);
  csqrt(y2,x3);
  x3.re = -x3.re;
  x3.im = -x3.im; // Ten jest ujemny
  csqrt(y2,x4);

  // Wyświetlamy wyniki:
  cout << "x1 = "; cmplxprint(x1);
  cout << "x2 = "; cmplxprint(x2);
  cout << "x3 = "; cmplxprint(x3);
  cout << "x4 = "; cmplxprint(x4);
}

// Program główny
//---------------

int main()
{
  SetConsoleOutputCP(CP_UTF8);
  SetConsoleCP(CP_UTF8);

  cout << setprecision(3)
       << fixed;
  cout <<
  "Równania dwukwadratowe typu\n"
  "  4    2\n"
  "ax + bx + c = 0\n"
  "---------------------------\n";

  be(1,-5,4);
  be(1,-10,9);
  be(4,7,-2);
  be(3,2,5);

  cout << endl;
  system("pause");
  return 0;
}
Wynik
Równania dwukwadratowe typu
  4    2
ax + bx + c = 0
---------------------------

Równanie: +1.000*x^4-5.000*x^2+4.000 = 0
x1 = -1.000
x2 = +1.000
x3 = -2.000
x4 = +2.000

Równanie: +1.000*x^4-10.000*x^2+9.000 = 0
x1 = -1.000
x2 = +1.000
x3 = -3.000
x4 = +3.000

Równanie: +4.000*x^4+7.000*x^2-2.000 = 0
x1 = +0.000-1.414i
x2 = +0.000+1.414i
x3 = -0.500
x4 = +0.500

Równanie: +3.000*x^4+2.000*x^2+5.000 = 0
x1 = -0.692+0.901i
x2 = +0.692-0.901i
x3 = -0.692-0.901i
x4 = +0.692+0.901i
Python (dodatek)
# Równanie czwartego stopnia
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0046
# ---------------------------

from math import sqrt

# Tutaj definiujemy
# dane wejściowe
# ------------------

# Dokładność porównania
# z zerem
epsy = 1e-12

# Definicja typu zespolonego
class cmplx:

    def __init__(self):
        self.re = 0.0
        self.im = 0.0

# Wyświetla + przed
# liczbą dodatnią,
# '-' przed ujemną
# ------------------
def pl(x):
    if x >= 0:
        print("+", end="")
    else:
        print("-", end="")
    print(f"{abs(x):.3f}", end="")

# Funkcja wylicza
# pierwiastek zespolony
# ----------------------
def csqrt(y):
    x = cmplx()
    a = y.re
    b = y.im
    c = sqrt(a * a + b * b)
    x.re = sqrt((c + a) / 2.0)
    x.im = sqrt((c - a) / 2.0)
    if b < 0:
        x.im = -x.im
    return x

# Funkcja wyświetlająca
# liczbę zespoloną
# ----------------------
def cmplxprint(x):
    # Część rzeczywistą
    # wyświetlamy zawsze
    pl(x.re)
    # Jeśli część urojona
    # jest różna od zera,
    # to ją wyświetlamy
    if abs(x.im) > epsy:
        pl(x.im)
        print("i", end="")
    print()

# Funkcja rozwiązująca
# równanie dwukwadratowe
# a,b,c - współczynniki
# wielomianu
# -----------------------
def be(a, b, c):
    print("\nRównanie: ", end="")
    pl(a)
    print("*x^4", end="")
    pl(b)
    print("*x^2", end="")
    pl(c)
    print(" = 0")

    y1 = cmplx()
    y2 = cmplx()

    # Obliczamy wyróżnik
    delta = b * b - 4.0 * a * c

    # Jeśli wyróżnik jest nieujemny,
    # wyliczamy pierwiastki
    # rzeczywiste
    if abs(delta) < epsy:
        y1.re = -b / 2.0 / a
        y2.re = y1.re
        y1.im = 0.0
        y2.im = 0.0
    elif delta > 0:
        delta = sqrt(delta)
        y1.re = (-b - delta) / 2 / a
        y2.re = (-b + delta) / 2 / a
        y1.im = 0.0
        y2_im = 0.0
    else:
        # Inaczej wyliczamy
        # pierwiastki zespolone
        delta = sqrt(-delta)
        y1.re = -b / 2.0 / a
        y2.re = y1.re
        y1.im = -delta / 2.0 / a
        y2.im =  delta / 2.0 / a

    # Obliczamy pierwiastki
    # zespolone rozwiązań
    # równania kwadratowego
    x1 = csqrt(y1)
    x1.re = -x1.re
    x1.im = -x1.im  # Ten jest ujemny
    x2 = csqrt(y1)
    x3 = csqrt(y2)
    x3.re = -x3.re
    x3.im = -x3.im  # Ten jest ujemny
    x4 = csqrt(y2)

    # Wyświetlamy wyniki:
    print("x1 = ", end="")
    cmplxprint(x1)
    print("x2 = ", end="")
    cmplxprint(x2)
    print("x3 = ", end="")
    cmplxprint(x3)
    print("x4 = ", end="")
    cmplxprint(x4)


# Program główny
# ---------------

print("Równania dwukwadratowe typu")
print("  4    2")
print("ax + bx + c = 0")
print("---------------------------")

be(1, -5, 4)
be(1, -10, 9)
be(4, 7, -2)
be(3, 2, 5)

print()
input("Naciśnij Enter...")

do podrozdziału  do strony 

Algorytm nr 2

Równanie czwartego stopnia o postaci:

możemy przekształcić do postaci:

Równanie to posiada pierwiastek równy zero. Pozostałe pierwiastki są pierwiastkami równania sześciennego i znajdujemy je metodami opisanymi w poprzednim rozdziale.

C++
// Równanie czwartego stopnia
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0047
//---------------------------

#include <iostream>
#include <windows.h>
#define _USE_MATH_DEFINES
#include <cmath>
#include <iomanip>

using namespace std;

// Tutaj definiujemy
// dane wejściowe
//------------------

// Dokładność porównania
// z zerem
double epsy = 1e-12;

// Wyświetla + przed
// liczbą dodatnią,
// '-' przed ujemną
//------------------
void pl(double x)
{
  if(x >= 0)
    cout << '+';
  else
    cout << '-';
  cout << fabs(x);
}

// Funkcja rozwiązująca
// równanie czwartego stopnia
// a,b,c,d - współczynniki
// --------------------------
void qe(double a, double b,
        double c, double d)
{
  double x1,x2,x3,p,q,delta;
  // Znacznik wyniku
  // zespolonego
  bool cmplx = false;

  cout << "\nRównanie: ";
  pl(a);
  cout << "*x^4";
  pl(b);
  cout << "*x^3";
  pl(c);
  cout << "*x^2";
  pl(d);
  cout << "*x = 0\n";

  // Modyfikujemy współczynniki
  // równania
  d /= a;
  c /= a;
  b /= a;
  a = b;
  b = c;
  c = d;

  // Obliczamy wyróżnik delta
  p = b-a*a/3.0;
  q = 2.0*a*a*a/27.0-a*b/3.0+c;
  delta = p*p*p/27.0+q*q/4.0;

  // Sprawdzamy przypadki

  if(fabs(delta) < epsy)
  {
    // 3 pierwiastki, 2 podwójne
    q = ((q > 0)-(q < 0))*
        pow(fabs(q)/2.0,1/3.0);
    x1 = -2.0*q-a/3.0;
    x2 = x3 = q-a/3.0;
  }
  else if(delta > 0)
  {
    // 1 pierwiastek rzeczywisty,
    // 2 zespolone
    cmplx = true; // Wynik zespolony
    q /= -2.0;
    delta = sqrt(delta);
    x1 = ((q+delta > 0)-
          (q+delta < 0))*
          pow(fabs(q+delta),1/3.0)+
         ((q-delta > 0)-
          (q-delta < 0))*
          pow(fabs(q-delta),1/3.0)-a/3.0;

    // Schematem Hornera dzielimy
    // wielomian równania sześciennego
    // przez dwumian (x - x1)
    double aa,bb,cc;
    aa = 1;
    bb = a + aa * x1;
    cc = b + bb * x1;

    // Obliczamy wyróżnik
    // równania kwadratowego
    delta = bb*bb-4.0*aa*cc;
    delta = sqrt(-delta);

    // Część rzeczywista
    x2 = - bb/2.0/aa;
    // Część urojona
    x3 = delta/2.0/aa;
  }
  else
  {
    // 3 pierwiastki rzeczywiste
    a /= 3.0;
    p = sqrt(-p);
    double pp = 2.0/sqrt(3.0)*p;
    q = 2.0*sqrt(3.0)*q/2.0/p/p/p;
    x1 =  pp*sin(asin(q)/3.0)-a;
    x2 = -pp*sin(asin(q)/3.0+M_PI/3.0)-a;
    x3 =  pp*cos(asin(q)/3.0+M_PI/6.0)-a;
  }
  cout << "x1 = ";
  pl(0.0);
  cout << "\nx2 = ";
  pl(x1);
  cout << endl;
  if(cmplx)
  {
    cout << "x3 = ";
    pl(x2);
    pl(-x3);
    cout << "i\n"
            "x4 = ";
    pl(x2);
    pl(x3);
    cout << "i";
  }
  else
  {
    cout << "x3 = ";
    pl(x2);
    cout << "\nx4 = ";
    pl(x3);
  }
  cout << endl;
}

// Program główny
//---------------

int main()
{
  SetConsoleOutputCP(CP_UTF8);
  SetConsoleCP(CP_UTF8);

  cout << setprecision(3)
       << fixed;
  cout <<
  "Równania czwartego stopnia typu\n"
  "  4    3    2\n"
  "ax + bx + cx + dx = 0\n"
  "-------------------------------\n";

  qe(1,3,3,1);
  qe(1,-6,12,-8);
  qe(1,9,27,27);
  qe(1,-6,11,-6);
  qe(1,-1,-16,-20);
  qe(1,-2,-10,-25);

  cout << endl;
  system("pause");
  return 0;
}
Wyniki
Równania czwartego stopnia typu
  4    3    2
ax + bx + cx + dx = 0
-------------------------------

Równanie: +1.000*x^4+3.000*x^3+3.000*x^2+1.000*x = 0
x1 = +0.000
x2 = -1.000
x3 = -1.000
x4 = -1.000

Równanie: +1.000*x^4-6.000*x^3+12.000*x^2-8.000*x = 0
x1 = +0.000
x2 = +2.000
x3 = +2.000
x4 = +2.000

Równanie: +1.000*x^4+9.000*x^3+27.000*x^2+27.000*x = 0
x1 = +0.000
x2 = -3.000
x3 = -3.000
x4 = -3.000

Równanie: +1.000*x^4-6.000*x^3+11.000*x^2-6.000*x = 0
x1 = +0.000
x2 = +2.000
x3 = +1.000
x4 = +3.000

Równanie: +1.000*x^4-1.000*x^3-16.000*x^2-20.000*x = 0
x1 = +0.000
x2 = +5.000
x3 = -2.000
x4 = -2.000

Równanie: +1.000*x^4-2.000*x^3-10.000*x^2-25.000*x = 0
x1 = +0.000
x2 = +5.000
x3 = -1.500-1.658i
x4 = -1.500+1.658i
Python (dodatek)
# Równanie czwartego stopnia
# (C)2019 mgr Jerzy Wałaszek
# Metody numeryczne 0047
# ---------------------------

from math import sqrt,pow,asin,sin,cos,pi

# Tutaj definiujemy
# dane wejściowe
# ------------------

# Dokładność porównania z zerem
epsy = 1e-12

# Wyświetla + przed liczbą dodatnią,
# '-' przed ujemną
# ---------------------------------
def pl(x):
    if x >= 0:
        print("+", end="")
    else:
        print("-", end="")
    print(f"{abs(x):.3f}", end="")

# Funkcja rozwiązująca
# równanie czwartego stopnia
# a,b,c,d - współczynniki
# --------------------------
def qe(a, b, c, d):
    # Znacznik wyniku zespolonego
    cmplx = False

    print("\nRównanie: ", end="")
    pl(a)
    print("*x^4", end="")
    pl(b)
    print("*x^3", end="")
    pl(c)
    print("*x^2", end="")
    pl(d)
    print("*x = 0")

    # Modyfikujemy współczynniki równania
    d /= a
    c /= a
    b /= a
    a = b
    b = c
    c = d

    # Obliczamy wyróżnik delta
    p = b-a*a/3
    q = 2*a*a*a/27-a*b/3+c
    delta = p*p*p/27+q*q/4

    # Sprawdzamy przypadki
    #---------------------

    if abs(delta) < epsy:
        # 3 pierwiastki, 2 podwójne
        sgn = (q > 0)-(q < 0)
        q = sgn*pow(abs(q)/2,1/3)
        x1 = -2*q-a/3
        x2 = q-a/3
        x3 = x2
    elif delta > 0:
        # 1 pierwiastek rzeczywisty,
        # 2 zespolone
        cmplx = True  # Wynik zespolony
        q /= -2.0
        delta = sqrt(delta)

        v1 = q+delta
        v2 = q-delta
        sgn1 = (v1 > 0)-(v1 < 0)
        sgn2 = (v2 > 0)-(v2 < 0)

        x1 = (sgn1*pow(abs(v1),1/3)
             +sgn2*pow(abs(v2),1/3)
             -a/3)

        # Schematem Hornera dzielimy
        # wielomian równania
        # sześciennego przez dwumian
        # (x - x1)
        aa = 1
        bb = a+aa*x1
        cc = b+bb*x1

        # Obliczamy wyróżnik
        # równania kwadratowego
        delta = bb*bb-4*aa*cc
        delta = sqrt(-delta)

        # Część rzeczywista
        x2 = -bb/2/aa
        # Część urojona
        x3 = delta/2/aa
    else:
        # 3 pierwiastki rzeczywiste
        a /= 3
        p = sqrt(-p)
        pp = 2/sqrt(3)*p
        q =  2*sqrt(3)*q/2/(p*p*p)
        x1 =   pp*sin(asin(q)/3)-a
        x2 = (-pp*sin(asin(q)/3
                +pi/3)-a)
        x3 = ( pp*cos(asin(q)/3
                +pi/6)-a)

    print("x1 = ", end="")
    pl(0.0)
    print("\nx2 = ", end="")
    pl(x1)
    print()

    if cmplx:
        print("x3 = ", end="")
        pl(x2)
        pl(-x3)
        print("i\nx4 = ", end="")
        pl(x2)
        pl(x3)
        print("i", end="")
    else:
        print("x3 = ", end="")
        pl(x2)
        print("\nx4 = ", end="")
        pl(x3)
    print()

# Program główny
# ---------------

print("Równania czwartego stopnia typu")
print("  4    3    2")
print("ax + bx + cx + dx = 0")
print("-------------------------------")

qe(1, 3, 3, 1)
qe(1, -6, 12, -8)
qe(1, 9, 27, 27)
qe(1, -6, 11, -6)
qe(1, -1, -16, -20)
qe(1, -2, -10, -25)

print()
input("Naciśnij Enter...")

do podrozdziału  do strony 

Algorytm nr 3

Jeśli uda ci się znaleźć jeden pierwiastek x1 równania ax4+bx3+cx2+dx+e = 0, to wielomian tego równania możesz podzielić za pomocą schematu Hornera przez dwumian (x - x1):

W rezultacie otrzymasz równanie sześcienne, które rozwiązujesz metodami opisanymi w poprzednim rozdziale. Problem sprowadza się zatem do znalezienia pierwiastka rzeczywistego. Jeśli taki pierwiastek istnieje, to znajdziemy go jedną z metod przybliżonych, np. metodą Newtona. Przyjrzyjmy się wykresowi funkcji wielomianowej czwartego stopnia:

obrazek

W zależności od znaku współczynnika a mamy dwa wykresy, tutaj w kolorze niebieskim i czerwonym. Pierwsza pochodna tej funkcji wyraża się wzorem:

Ponieważ pochodna jest wielomianem sześciennym, to zawsze istnieje takie x0, dla którego pochodna f'(x0) = 0. Wszystkie takie punkty są punktami krytycznymi funkcji wyjściowej. Jeśli pochodna w danym punkcie jest zerowa, to styczna w tym punkcie do wykresu funkcji jest równoległa do osi OX i metoda Newtona załamuje się. Zatem poszukując pierwiastka musimy tak dobrać punkt startowy, aby na drodze do pierwiastka pierwsza pochodna nie zerowała się. Musimy więc najpierw znaleźć wszystkie punkty krytyczne i dokonać odpowiednich wyborów. Punkty krytyczne znajdziemy rozwiązując równanie:

Równanie to rozwiązujemy metodą z poprzedniego rozdziału. Jako rozwiązania interesują nas tylko pierwiastki rzeczywiste, których może być jeden lub trzy. Rozważmy te przypadki:

Jeden punkt krytyczny K

Funkcja wyjściowa ma w tym przypadku jedno maksimum lub jedno minimum w punkcie xK.

obrazek

Zwrot ramion wykresu zależy od znaku współczynnika a. Jeśli a jest dodatnie, to ramiona są skierowane do góry, a punkt K jest minimum funkcji (jak na obrazku powyżej). Jeśli a jest ujemne, to ramiona są skierowane w dół i punkt K jest maksimum funkcji:

obrazek

Sprawdzamy teraz wartość f(xK):

W takim przypadku xK jest pierwiastkiem równania wyjściowego i możemy pominąć metodę Newtona, przyjmując x1 = xK.

Mamy maksimum/minimum w xK i dwa pierwiastki po obu stronach xK. Za punkt startowy wybieramy x0 = xK - 1 lub x0 = xK + 1 i szukamy pierwiastka metodą Newtona.

W pozostałych przypadkach funkcja f(x) nie ma pierwiastków rzeczywistych. Obliczenia przerywamy.

Trzy punkty krytyczne K1, K2 i K3

Funkcja wyjściowa f(x) posiada minima/maksima lokalne:

obrazek

obrazek

Porządkujemy punkty w kolejności:

Sprawdzamy, czy w którymś z tych punktów funkcja f(x) przyjmuje wartość 0. Jeśli tak, to mamy jeden pierwiastek x1 i pomijamy metodę Newtona.

Sprawdzamy, czy w dwóch sąsiednich punktach xK1 i xK2 lub xK2 i xK3 wartości funkcji mają różne znaki. Jeśli tak, to za punkt startowy x0 wybieramy średnią arytmetyczną tych punktów i uruchamiamy metodę Newtona, aby znaleźć pierwiastek x1.

Sprawdzamy przypadki:

Za punkt startowy wybieramy x0 = xK1 - 1 i uruchamiamy metodę Newtona.

Za punkt startowy wybieramy x0 = xK3 + 1 i uruchamiamy metodę Newtona.

W przeciwnym razie funkcja f(x) nie ma pierwiastków rzeczywistych i obliczenia przerywamy.

Metoda Newtona

Gdy zostanie ustalony punkt startowy x0, wykorzystujemy metodę Newtona do znalezienia pierwiastka rzeczywistego x1 funkcji wyjściowej f(x).

Schemat Hornera

Gdy znany jest pierwiastek x1, dzielimy wielomian funkcji wyjściowej f(x) przez dwumian (x - x1). Zadanie to wykonujemy przy pomocy schematu Hornera:

Równanie sześcienne

W rezultacie otrzymujemy wielomian sześcienny. Rozwiązujemy równanie a'x3+b'x2+c'x+d' = 0. Otrzymujemy pozostałe 3 pierwiastki x2, x3 i x4 i mamy pełne rozwiązanie równania czwartego stopnia.

Powyższa metoda pozwala znaleźć wszystkie pierwiastki równania czwartego stopnia, jeśli wśród nich występują pierwiastki rzeczywiste.

Metoda postępowania jest zatem następująca:

  1. Wyznaczamy punkty krytyczne funkcji f(x) = ax4+bx3+cx2+dx+e.
  2. Na podstawie punktów krytycznych sprawdzamy, czy wielomian funkcji ma pierwiastek rzeczywisty. Jeśli tak, to wyznaczamy go metodą Newtona. Jeśli nie, obliczenia przerywamy.
  3. Dzielimy za pomocą schematu Hornera wielomian funkcji przez dwumian x - x1, gdzie x1 jest pierwiastkiem wyznaczonym w punkcie 2. W wyniku otrzymujemy wielomian sześcienny.
  4. Rozwiązujemy równanie sześcienne i otrzymujemy pozostałe trzy pierwiastki.

Jak widzisz, metoda ta łączy ze sobą kilka opisanych wcześniej metod. Rozwiązanie otrzymamy, jeśli równanie wyjściowe posiada pierwiastek rzeczywisty. W przypadku samych pierwiastków zespolonych algorytm zawodzi. Należy wtedy zastosować jedną z metod ogólnych, które opisujemy w dalszej części tego rozdziału.

Przykładowy program wykorzystujący opisaną tutaj metodę jest następujący:

C++
// Równanie czwartego stopnia
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0048
//---------------------------

#include <iostream>
#include <windows.h>
#define _USE_MATH_DEFINES
#include <cmath>
#include <iomanip>

using namespace std;

// Tutaj definiujemy
// dane wejściowe
//------------------

// Dokładność porównania
// z zerem
double epsy = 1e-12;

// Wyświetla + przed
// liczbą dodatnią,
// '-' przed ujemną
//------------------
void pl(double x)
{
  if(x >= 0)
    cout << '+';
  else
    cout << '-';
  cout << fabs(x);
}

// Funkcja oblicza wartość
// wielomianu metodą Hornera
//--------------------------
double f(double a, double b,
         double c, double d,
         double e, double x)
{
  double w = a;

  w = w * x + b;
  w = w * x + c;
  w = w * x + d;
  w = w * x + e;

  return w;
}

// Funkcja rozwiązująca
// równanie sześcienne
// a,b,c,d - współczynniki
//           wielomianu
// cmplx - true, x1 = pierwiastek,
//               x2 = re,
//               x3 = +/- im
//       - false,
//               x1,x2,x3 =
//               pierwiastki
//               rzeczywiste
// x1,x2,x3 - pierwiastki
//--------------------------------
void ce(double a, double b,
        double c, double d,
        bool & cmplx,
        double & x1,
        double & x2,
        double & x3)
{
  double p,q,delta;

  // Znacznik wyniku zespolonego
  cmplx = false;

  // Modyfikujemy współczynniki
  // równania
  d /= a;
  c /= a;
  b /= a;
  a = b;
  b = c;
  c = d;

  // Obliczamy wyróżnik delta
  p = b-a*a/3.0;
  q = 2.0*a*a*a/27.0-a*b/3.0+c;
  delta = p*p*p/27.0+q*q/4.0;

  // Sprawdzamy przypadki
  if(fabs(delta) < epsy)
  { // 3 pierwiastki, 2 podwójne
    q  = ((q > 0) - (q < 0))*
         pow(fabs(q)/2.0,1/3.0);
    x1 = -2.0*q-a/3.0;
    x2 = q-a/3.0;
    x3 = x2;
  }
  else if(delta > 0)
  { // 1 pierwiastek rzeczywisty,
    // 2 zespolone

    // Wynik zespolony
    cmplx = true;
    q /= -2.0;
    delta = sqrt(delta);
    x1 = ((q+delta > 0)-(q+delta < 0))*
         pow(fabs(q+delta),1/3.0)+
         ((q-delta > 0)-(q-delta < 0))*
         pow(fabs(q-delta),1/3.0)-a/3.0;

    // Schematem Hornera dzielimy
    // wielomian równania sześciennego
    // przez dwumian (x - x1)
    double aa,bb,cc;
    aa = 1;
    bb = a+aa*x1;
    cc = b+bb*x1;

    // Obliczamy wyróżnik
    // równania kwadratowego
    delta = bb*bb-4*aa*cc;
    delta = sqrt(-delta);

    // Część rzeczywista
    x2 = -bb/2.0/aa;
    // Część urojona
    x3 = delta/2.0/aa;
  }
  else // 3 pierwiastki rzeczywiste
  {
    a /= 3.0;
    p = sqrt(-p);
    double pp = 2.0/sqrt(3.0)* p;
    q = 3.0*sqrt(3.0)*q/2.0/p/p/p;
    x1 =  pp*sin(asin(q)/3.0)-a;
    x2 = -pp*sin(asin(q)/3.0+M_PI/3.0)-a;
    x3 =  pp*cos(asin(q)/3.0+M_PI/6.0)-a;
  }
}

// Funkcja rozwiązująca równanie
// czwartego stopnia
// a,b,c,d,e - współczynniki
//             wielomianu
//------------------------------
void qe(double a, double b,
        double c, double d,
        double e)
{
  double x0,x1,x2,x3,x4;
  bool cmplx,noresult,newton;

  cout << "\nRównanie: ";
  pl(a);
  cout << "*x^4";
  pl(b);
  cout << "*x^3";
  pl(c);
  cout << "*x^2";
  pl(d);
  cout << "*x";
  pl(e);
  cout << " = 0\n";

  // Wyznaczamy pierwiastki pochodnej

  ce(4.0*a,3.0*b,2.0*c,
     d,cmplx,x1,x2,x3);
  // Znacznik braku pierwiastków
  noresult = false;
  // Znacznik obliczania pierwiastka
  // metodą Newtona
  newton = true;

  if(cmplx)
  { // Jeden pierwiastek rzeczywisty

    // Obliczamy wartość w punkcie xk
    double yk = f(a,b,c,d,e,x1);

    if(fabs(yk) < epsy)
      // Mamy jeden pierwiastek
      newton = false;
    else if(yk * a < 0)
      // Punkt startowy
      // dla metody Newtona
      x0 = x1 - 1;
    else
      // Brak pierwiastków
      // rzeczywistych
      noresult = true;
  }
  else
  { // Trzy pierwiastki rzeczywiste

    // Porządkujemy punkty krytyczne
    if(x1 > x2) swap(x1,x2);
    if(x2 > x3) swap(x2,x3);
    if(x1 > x2) swap(x1,x2);

    double yk1,yk2,yk3;

    // Obliczamy wartości wielomianu
    // w punktach krytycznych
    yk1 = f(a,b,c,d,e,x1);
    yk2 = f(a,b,c,d,e,x2);
    yk3 = f(a,b,c,d,e,x3);

    // Sprawdzamy, czy w którymś
    // z punktów krytycznych
    // wielomian zeruje się
    if(fabs(yk1) < epsy)
      newton = false;
    else if(fabs(yk2) < epsy)
    {
      newton = false;
      x1 = x2;
    }
    else if(fabs(yk3) < epsy)
    {
      newton = false;
      x1 = x3;
    }
    // Punkty startowe
    // dla metody Newtona
    else if(yk1 * yk2 < 0)
      x0 = (x1 + x2) / 2.0;
    else if(yk2 * yk3 < 0)
      x0 = (x2 + x3) / 2.0;
    else if(yk1 * a < 0)
      x0 = x1 - 1;
    else if(yk3 * a < 0)
      x0 = x3 + 1;
    else noresult = true;
  }

  // Jeśli brak pierwiastków,
  // przerywamy obliczenia
  if(noresult)
  {
    cout <<
    "BRAK PIERWIASTKÓW RZECZYWISTYCH\n"
    "Obliczenia zostały przerwane!!!\n\n";
    return;
  }

  // Jeśli nie znaleziono pierwiastka,
  // uruchamiamy metodę Newtona
  if(newton)
  {
    // Dokładność wyznaczania zera
    double epsx = 1e-14;
    // Maksymalna liczba obiegów
    int n = 64;
    double f0,f1;
    bool result = false;

    while(--n)
    {
       // Obliczamy wartość
       // funkcji w punkcie x0
       f0 = f(a,b,c,d,e,x0);

       // Sprawdzamy, czy funkcja
       // jest dostatecznie
       // bliska zeru
       if(fabs(f0) < epsy)
       {
         result = true;
         break;
       }

       // Obliczamy wartość
       // pierwszej pochodnej funkcji
       f1 = f(0,4.0*a,3.0*b,2.0*c,d,x0);

       // Zapamiętujemy bieżące
       // przybliżenie
       x1 = x0;

       // Obliczamy kolejne przybliżenie
       x0 -= f0/f1;

       // Sprawdzamy, czy odległość
       // pomiędzy dwoma ostatnimi
       // przybliżeniami jest mniejsza
       // od założonej dokładności
       if(fabs(x1 - x0) < epsx)
       {
         result = true;
         break;
       }

       // Kontynuujemy obliczenia
    }

    if(!result)
    {
      cout <<
      "BŁĄD W METODZIE NEWTONA\n"
      "Obliczenia przerwane!!!\n\n";
      return;
    }

    // Pierwszy pierwiastek
    // z metody Newtona
    x1 = x0;
  }

  // W x1 mamy pierwiastek rzeczywisty
  // Schematem Hornera dzielimy
  // wielomian równania przez
  // dwumian (x - x1)
  double aa,bb,cc,dd;
  aa = a;
  bb = b + aa * x1;
  cc = c + bb * x1;
  dd = d + cc * x1;

  // Obliczamy pierwiastki
  // wynikowego równania
  // sześciennego
  ce(aa,bb,cc,dd,cmplx,x2,x3,x4);

  // Wyświetlamy wyniki
  cout << "x1 = ";
  pl(x1);
  cout << "\nx2 = ";
  pl(x2);
  cout << endl;
  if(cmplx)
  {
    cout << "x3 = ";
    pl(x3);
    pl(-x4);
    cout << "i\n"
            "x4 = ";
    pl(x3);
    pl(x4);
    cout << "i";
  }
  else
  {
    cout << "x3 = ";
    pl(x3);
    cout << "\nx4 = ";
    pl(x4);
  }
  cout << endl;
}

// Program główny
//---------------

int main()
{
  SetConsoleOutputCP(CP_UTF8);
  SetConsoleCP(CP_UTF8);

  cout << setprecision(3)
       << fixed;
  cout <<
  "Równania czwartego stopnia typu\n"
  "  4    3    2\n"
  "ax + bx + cx + dx + e = 0\n"
  "-------------------------------\n";

  qe(1,-10,35,-50,24);
  qe(1,-4,3,4,-4);
  qe(1,1,-7,-1,6);

  cout << endl;
  system("pause");
  return 0;
}
Wynik
Równania czwartego stopnia typu
  4    3    2
ax + bx + cx + dx + e = 0
-------------------------------

Równanie: +1.000*x^4-10.000*x^3+35.000*x^2-50.000*x+24.000 = 0
x1 = +2.000
x2 = +3.000
x3 = +1.000
x4 = +4.000

Równanie: +1.000*x^4-4.000*x^3+3.000*x^2+4.000*x-4.000 = 0
x1 = +2.000
x2 = +1.000
x3 = -1.000
x4 = +2.000

Równanie: +1.000*x^4+1.000*x^3-7.000*x^2-1.000*x+6.000 = 0
x1 = -1.000
x2 = +1.000
x3 = -3.000
x4 = +2.000
Python (dodatek)
# Równanie czwartego stopnia
# (C)2019 mgr Jerzy Wałaszek
# Metody numeryczne 0048
# ---------------------------

from math import asin,cos,pi,pow,sin,sqrt

# Tutaj definiujemy dane wejściowe
# --------------------------------

# Dokładność porównania z zerem
epsy = 1e-12

# Wyświetla + przed
# liczbą dodatnią,
# '-' przed ujemną
# ------------------
def pl(x):
    if x >= 0:
        print("+", end="")
    else:
        print("-", end="")
    print(f"{abs(x):.3f}", end="")

# Funkcja oblicza wartość
# wielomianu metodą Hornera
# --------------------------
def f(a, b, c, d, e, x):
    w = a

    w = w * x + b
    w = w * x + c
    w = w * x + d
    w = w * x + e

    return w

# Funkcja rozwiązująca
# równanie sześcienne
# a,b,c,d - współczynniki
#           wielomianu
# cmplx - true, x1 = pierwiastek,
#               x2 = re,
#               x3 = +/- im
#       - false,
#               x1,x2,x3 =
#               pierwiastki
#               rzeczywiste
# x1,x2,x3 - pierwiastki
# --------------------------------
def ce(a, b, c, d):
    # Znacznik wyniku zespolonego
    cmplx = False

    # Modyfikujemy współczynniki
    # równania
    d /= a
    c /= a
    b /= a
    a = b
    b = c
    c = d

    # Obliczamy wyróżnik delta
    p = b-a*a/3
    q = 2.0*a*a*a/27-a*b/3+c
    delta = p*p*p/27+q*q/4

    # Sprawdzamy przypadki
    if abs(delta) < epsy:
        # 3 pierwiastki, 2 podwójne
        sgn = (q > 0)-(q < 0)
        q = sgn*pow(abs(q)/2,1/3)
        x1 = -2.0*q-a/3
        x2 = q-a/3
        x3 = x2
    elif delta > 0:
        # 1 pierwiastek rzeczywisty,
        # 2 zespolone

        # Wynik zespolony
        cmplx = True
        q /= -2
        delta = sqrt(delta)

        v1 = q+delta
        v2 = q-delta
        sgn1 = (v1 > 0)-(v1 < 0)
        sgn2 = (v2 > 0)-(v2 < 0)

        x1 = (sgn1*pow(abs(v1),1/3)
             +sgn2*pow(abs(v2),1/3)
             -a/3)

        # Schematem Hornera dzielimy
        # wielomian równania
        # sześciennego przez dwumian
        # (x - x1)
        aa = 1
        bb = a + aa * x1
        cc = b + bb * x1

        # Obliczamy wyróżnik
        # równania kwadratowego
        delta = bb*bb-4*aa*cc
        delta = sqrt(-delta)

        # Część rzeczywista
        x2 = -bb/2/aa
        # Część urojona
        x3 = delta/2/aa
    else:
        # 3 pierwiastki rzeczywiste
        a /= 3
        p  = sqrt(-p)
        pp = 2/sqrt(3)*p
        q  = 3*sqrt(3)*q/2/(p*p*p)
        x1 = pp*sin(asin(q)/3)-a
        x2 = (-pp*sin(asin(q)/3+pi/3)-a)
        x3 = ( pp*cos(asin(q)/3+pi/6)-a)

    return cmplx, x1, x2, x3

# Funkcja rozwiązująca równanie
# czwartego stopnia
# a,b,c,d,e - współczynniki
#             wielomianu
# ------------------------------
def qe(a, b, c, d, e):
    print("\nRównanie: ", end="")
    pl(a)
    print("*x^4", end="")
    pl(b)
    print("*x^3", end="")
    pl(c)
    print("*x^2", end="")
    pl(d)
    print("*x", end="")
    pl(e)
    print(" = 0")

    # Wyznaczamy pierwiastki pochodnej
    cmplx,x1,x2,x3 = ce(4*a,3*b,2*c,d)
    # Znacznik braku pierwiastków
    noresult = False
    # Znacznik obliczania pierwiastka
    # metodą Newtona
    newton = True

    if cmplx:
        # Jeden pierwiastek rzeczywisty

        # Obliczamy wartość w punkcie xk
        yk = f(a, b, c, d, e, x1)

        if abs(yk) < epsy:
            # Mamy jeden pierwiastek
            newton = False
        elif yk * a < 0:
            # Punkt startowy
            # dla metody Newtona
            x0 = x1 - 1
        else:
            # Brak pierwiastków
            # rzeczywistych
            noresult = True
    else:
        # Trzy pierwiastki rzeczywiste

        # Porządkujemy punkty krytyczne
        if x1 > x2:
            x1, x2 = x2, x1
        if x2 > x3:
            x2, x3 = x3, x2
        if x1 > x2:
            x1, x2 = x2, x1

        # Obliczamy wartości wielomianu
        # w punktach krytycznych
        yk1 = f(a, b, c, d, e, x1)
        yk2 = f(a, b, c, d, e, x2)
        yk3 = f(a, b, c, d, e, x3)

        # Sprawdzamy, czy w którymś
        # z punktów krytycznych
        # wielomian zeruje się
        if abs(yk1) < epsy:
            newton = False
        elif abs(yk2) < epsy:
            newton = False
            x1 = x2
        elif abs(yk3) < epsy:
            newton = False
            x1 = x3
        # Punkty startowe
        # dla metody Newtona
        elif yk1 * yk2 < 0:
            x0 = (x1+x2)/2
        elif yk2 * yk3 < 0:
            x0 = (x2+x3)/2
        elif yk1 * a < 0:
            x0 = x1-1
        elif yk3 * a < 0:
            x0 = x3+1
        else:
            noresult = True

    # Jeśli brak pierwiastków,
    # przerywamy obliczenia
    if noresult:
        print(
        "BRAK PIERWIASTKÓW RZECZYWISTYCH\n"
        "Obliczenia zostały przerwane!!!\n")
        return

    # Jeśli nie znaleziono pierwiastka,
    # uruchamiamy metodę Newtona
    if newton:
        # Dokładność wyznaczania zera
        epsx = 1e-14
        # Maksymalna liczba obiegów
        n = 64
        bool_res = False

        while n > 0:
            n -= 1
            # Obliczamy wartość
            # funkcji w punkcie x0
            f0 = f(a, b, c, d, e, x0)

            # Sprawdzamy, czy funkcja
            # jest dostatecznie
            # bliska zeru
            if abs(f0) < epsy:
                bool_res = True
                break

            # Obliczamy wartość
            # pierwszej pochodnej funkcji
            f1 = f(0,4*a,3*b,2*c,d,x0)

            # Zapamiętujemy bieżące
            # przybliżenie
            x1 = x0

            # Obliczamy kolejne
            # przybliżenie
            x0 -= f0/f1

            # Sprawdzamy, czy odległość
            # pomiędzy dwoma ostatnimi
            # przybliżeniami jest mniejsza
            # od założonej dokładności
            if abs(x1 - x0) < epsx:
                bool_res = True
                break

            # Kontynuujemy obliczenia

        if not bool_res:
            print(
            "BŁĄD W METODZIE NEWTONA\n"
            "Obliczenia przerwane!!!\n")
            return

        # Pierwszy pierwiastek
        # z metody Newtona
        x1 = x0

    # W x1 mamy pierwiastek rzeczywisty
    # Schematem Hornera dzielimy
    # wielomian równania przez
    # dwumian (x - x1)
    aa = a
    bb = b + aa * x1
    cc = c + bb * x1
    dd = d + cc * x1

    # Obliczamy pierwiastki
    # wynikowego równania
    # sześciennego
    cmplx,x2,x3,x4 = ce(aa,bb,cc,dd)

    # Wyświetlamy wyniki
    print("x1 = ", end="")
    pl(x1)
    print("\nx2 = ", end="")
    pl(x2)
    print()
    if cmplx:
        print("x3 = ", end="")
        pl(x3)
        pl(-x4)
        print("i\nx4 = ", end="")
        pl(x3)
        pl(x4)
        print("i", end="")
    else:
        print("x3 = ", end="")
        pl(x3)
        print("\nx4 = ", end="")
        pl(x4)
    print()

# Program główny
# ---------------

print("Równania czwartego stopnia typu\n"
      "  4    3    2\n"
      "ax + bx + cx + dx + e = 0\n"
      "-------------------------------")

qe(1, -10, 35, -50, 24)
qe(1, -4, 3, 4, -4)
qe(1, 1, -7, -1, 6)

print()
input("Naciśnij Enter...")

do podrozdziału  do strony 

Algorytm nr 4

Równanie czwartego stopnia można również rozwiązać algebraicznie za pomocą jednej z kilku metod. Tutaj przedstawimy metodę, która wykorzystuje pośrednie równanie sześcienne. Metoda pochodzi od włoskiego matematyka Lodovico Ferrari. Najpierw zobaczmy, jaką naturę mogą mieć pierwiastki równania czwartego stopnia:

Mamy ogólne równanie czwartego stopnia:

Załóżmy, że równanie to posiada pierwiastek rzeczywisty x1. W takim przypadku wielomian równania czwartego stopnia możemy zawsze podzielić przez dwumian (x - x1):

Pozostałe 3 pierwiastki są pierwiastkami równania:

Ponieważ jest to równanie sześcienne, to pozostałe 3 pierwiastki mogą być albo wszystkie rzeczywiste, albo jeden rzeczywisty i dwa zespolone. Wynika z tego, iż równanie czwartego stopnia może mieć:

Metoda rozwiązywania równania czwartego stopnia jest następująca:

Mamy ogólne równanie czwartego stopnia:

obrazek

Wyliczamy 3 kolejne współczynniki wg wzorów:

Z wyliczonych współczynników tworzymy pomocnicze równanie sześcienne:

Równanie to rozwiązujemy za pomocą metod opisanych w poprzednim rozdziale. Otrzymujemy trzy pierwiastki y1, y2 i y3. Wybieramy z nich dwa pierwiastki, które są różne od zera (jeśli mamy jeden pierwiastek rzeczywisty i dwa zespolone, zawsze wybieramy pierwiastki zespolone, które są liczbami sprzężonymi) i wyliczamy ich pierwiastki (mogą być zespolone):

Dodatkowo wyliczamy:

Pierwiastki równania wyjściowego otrzymujemy ze wzorów:

W działaniach mogą pojawiać się liczby zespolone, dlatego rachunki najlepiej przeprowadzać na liczbach zespolonych, dzięki czemu unikniemy rozważania różnych przypadków. Podobnie postąpiliśmy w algorytmie nr 1. Zasady działań na liczbach zespolonych są następujące (więcej na temat liczb zespolonych znajdziesz tutaj):


Poniższy program jest przykładową realizacją tego algorytmu:

C++
// Równanie czwartego stopnia
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0049
//---------------------------

#include <iostream>
#include <windows.h>
#define _USE_MATH_DEFINES
#include <cmath>
#include <iomanip>

using namespace std;

// Tutaj definiujemy
// dane wejściowe
//------------------

// Dokładność porównania
// z zerem
double epsy = 1e-12;

// Liczby zespolone
//-----------------

// Definicja typu zespolonego
struct cmplx
{
  double re, im;
};

// Mnożenie liczb zespolonych
// c = a * b
//----------------------------
void cmplx_mul(cmplx a,
               cmplx b,
               cmplx & c)
{
  c.re = a.re*b.re-a.im*b.im;
  c.im = a.re*b.im+a.im*b.re;
}

// Dzielenie liczb zespolonych
// c = a / b
//----------------------------
void cmplx_div(cmplx a,
               cmplx b,
               cmplx & c)
{
  double d = b.re*b.re+b.im*b.im;
  c.re = (a.re*b.re+a.im*b.im)/d;
  c.im = (a.im*b.re-a.re*b.im)/d;
}

// Pierwiastkowanie liczb zespolonych
// b = sqrt(a)
//-----------------------------------
void cmplx_sqrt(cmplx a,
                cmplx & b)
{
  double x,y;
  x = a.re;
  y = a.im;
  double c = sqrt(x*x+y*y);
  b.re = sqrt((c+x)/2.0);
  b.im = sqrt((c-x)/2.0);
  if(a.im < 0)
    b.im = -b.im;
}

// Wyświetla + przed
// liczbą dodatnią,
// '-' przed ujemną
//------------------
void pl(double x)
{
  if(x >= 0)
    cout << '+';
  else
    cout << '-';
  cout << fabs(x);
}

// Wyświetlanie liczby
// zespolonej
void cmplx_print(cmplx a)
{
  pl(a.re);
  if(fabs(a.im) >= epsy)
  {
     pl(a.im);
     cout << "i";
  }
  cout << endl;
}

// Funkcja rozwiązująca
// równanie sześcienne
// a,b,c,d - współczynniki
//           wielomianu
// cmplx - true, x1 = pierwiastek,
//               x2 = re,
//               x3 = +/- im
//        false, x1,x2,x3 = pierwiastki
//               rzeczywiste
// x1,x2,x3 - pierwiastki
//-------------------------------------
void ce(double a, double b,
        double c, double d,
        bool & cmpl,
        double & x1,
        double & x2,
        double & x3)
{
  double p,q,delta;

  // Znacznik wyniku
  // zespolonego
  cmpl = false;

  // Modyfikujemy współczynniki
  // równania
  d /= a;
  c /= a;
  b /= a;
  a = b;
  b = c;
  c = d;

  // Obliczamy wyróżnik delta
  p = b-a*a/3.0;
  q = 2.0*a*a*a/27.0-a*b/3.0+c;
  delta = p*p*p/27.0+q*q/4.0;

  // Sprawdzamy przypadki
  if(fabs(delta) < epsy)
  {
    // 3 pierwiastki, 2 podwójne
    q  = ((q > 0)-(q < 0))*
         pow(fabs(q)/2.0,1/3.0);
    x1 = -2*q-a/3.0;
    x2 = x3 = q-a/3.0;
  }
  else if(delta > 0)
  {
    // 1 pierwiastek rzeczywisty,
    // 2 zespolone
    cmpl = true; // Wynik zespolony
    q /= -2.0;
    delta = sqrt(delta);
    x1 = ((q+delta > 0)-
          (q+delta < 0))*
         pow(fabs(q+delta),1/3.0)+
         ((q-delta > 0)-(q-delta < 0))*
         pow(fabs(q-delta),1/3.0)-a/3.0;

    // Schematem Hornera dzielimy
    // wielomian równania sześciennego
    // przez dwumian (x - x1)
    double aa,bb,cc;

    aa = 1;
    bb = a+aa*x1;
    cc = b+bb*x1;

    // Obliczamy wyróżnik
    // równania kwadratowego
    delta = bb*bb-4.0*aa*cc;
    delta = sqrt(-delta);

    // Część rzeczywista
    x2 = -bb/2.0/aa;
    // Część urojona
    x3 = delta/2/aa;
  }
  else
  {
    // 3 pierwiastki rzeczywiste
    a /= 3.0;
    p = sqrt(-p);
    double pp = 2.0/sqrt(3.0)*p;
    q = 3.0*sqrt(3.0)*q/2.0/p/p/p;
    x1 =  pp*sin(asin(q)/3.0)-a;
    x2 = -pp*sin(asin(q)/3.0+M_PI/3.0)-a;
    x3 =  pp*cos(asin(q)/3.0+M_PI/6)-a;
  }
}

// Funkcja rozwiązująca
// równanie czwartego stopnia
// a,b,c,d,e - współczynniki
//             wielomianu
//---------------------------
void qe(double a, double b,
        double c, double d,
        double e)
{
  cout << "\nRównanie: ";
  pl(a);
  cout << "*x^4";
  pl(b);
  cout << "*x^3";
  pl(c);
  cout << "*x^2";
  pl(d);
  cout << "*x";
  pl(e);
  cout << " = 0\n";

  double f,g,h;

  // Wyliczamy współczynniki
  f = (c-3.0*b*b/8.0/a)/a;
  g = (d+b*b*b/8.0/a/a-b*c/2.0/a)/a;
  h = (e-3.0*b*b*b*b/256.0/a/a/a+
       b*b*c/16.0/a/a-
       b*d/4.0/a)/a;

  double x1,x2,x3;
  bool cmpl;

  // Tworzymy pomocnicze równanie
  // sześcienne i wyliczamy jego
  // pierwiastki
  ce(1,f/2.0,(f*f-4.0*h)/16.0,
     -g*g/64.0,cmpl,x1,x2,x3);
  cmplx y1, y2;
  // Pierwiastki zespolone
  if(cmpl)
  {
    y1.re =  y2.re = x2;
    y1.im = -x3;
    y2.im =  x3;
  }
  else
  {
    // Wybieramy dwa niezerowe
    // pierwiastki
    y1.im = y2.im = 0;
    if(fabs(x1) < epsy)
    {
      y1.re = x2;
      y2.re = x3;
    }
    else if(fabs(x2) < epsy)
    {
      y1.re = x1;
      y2.re = x3;
    }
    else
    {
      y1.re = x1;
      y2.re = x2;
    }
  }

  // Obliczamy ich
  // pierwiastki zespolone
  cmplx p,q,r,t,u;
  double s;

  cmplx_sqrt(y1,p);
  cmplx_sqrt(y2,q);

  // Wyliczamy współczynniki s i r
  s = b/4.0/a;
  cmplx_mul(p,q,t);
  u.re = -g/8.0;
  u.im = 0;
  cmplx_div(u,t,r);

  // Obliczamy pierwiastki
  // zespolone równania
  // czwartego stopnia
  cmplx r1,r2,r3,r4;

  r1.re = p.re+q.re+r.re-s;
  r1.im = p.im+q.im+r.im;

  r2.re = p.re-q.re-r.re-s;
  r2.im = p.im-q.im-r.im;

  r3.re = -p.re+q.re-r.re-s;
  r3.im = -p.im+q.im-r.im;

  r4.re = -p.re-q.re+r.re-s;
  r4.im = -p.im-q.im+r.im;

  // Wyświetlamy wyniki
  cout << "x1 = "; cmplx_print(r1);
  cout << "x2 = "; cmplx_print(r2);
  cout << "x3 = "; cmplx_print(r3);
  cout << "x4 = "; cmplx_print(r4);
}

// Program główny
//---------------

int main()
{
  cout << setprecision(3)
       << fixed;

  SetConsoleOutputCP(CP_UTF8);
  SetConsoleCP(CP_UTF8);

  cout <<
  "Równania czwartego stopnia typu\n"
  "  4    3    2\n"
  "ax + bx + cx + dx + e = 0\n"
  "-------------------------------\n";

  qe(1,-10,35,-50,24);
  qe(1,-4,3,4,-4);
  qe(1,1,-7,-1,6);
  qe(5,5,5,5,5);

  cout << endl;
  system("pause");
  return 0;
}
Wynik
Równania czwartego stopnia typu
  4    3    2
ax + bx + cx + dx + e = 0
-------------------------------

Równanie: +1.000*x^4-10.000*x^3+35.000*x^2-50.000*x+24.000 = 0
x1 = +4.000
x2 = +2.000
x3 = +3.000
x4 = +1.000

Równanie: +1.000*x^4-4.000*x^3+3.000*x^2+4.000*x-4.000 = 0
x1 = +2.000
x2 = +2.000
x3 = +1.000
x4 = -1.000

Równanie: +1.000*x^4+1.000*x^3-7.000*x^2-1.000*x+6.000 = 0
x1 = -1.000
x2 = +2.000
x3 = +1.000
x4 = -3.000

Równanie: +5.000*x^4+5.000*x^3+5.000*x^2+5.000*x+5.000 = 0
x1 = +0.309+0.951i
x2 = -0.809-0.588i
x3 = -0.809+0.588i
x4 = +0.309-0.951i
Python (dodatek)
# Równanie czwartego stopnia
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0049
# --------------------------

from math import asin,cos,pi,pow,sin,sqrt

# Tutaj definiujemy
# dane wejściowe
# -----------------

# Dokładność porównania
# z zerem
epsy = 1e-12

# Liczby zespolone
# ----------------

# Definicja typu zespolonego
class cmplx:

    def __init__(self):
        self.re = 0.0
        self.im = 0.0

# Mnożenie liczb zespolonych
# c = a * b
#---------------------------
def cmplx_mul(a, b):
    c = cmplx()
    c.re = a.re*b.re-a.im*b.im
    c.im = a.re*b.im+a.im*b.re
    return c

# Dzielenie liczb zespolonych
# c = a / b
#----------------------------
def cmplx_div(a, b):
    c = cmplx()
    d = b.re*b.re+b.im*b.im
    c.re = (a.re*b.re+a.im*b.im)/d
    c.im = (a.im*b.re-a.re*b.im)/d
    return c


# Pierwiastkowanie liczb zespolonych
# b = sqrt(a)
#-----------------------------------
def cmplx_sqrt(a):
    b = cmplx()
    x = a.re
    y = a.im
    c = sqrt(x*x+y*y)
    b.re = sqrt((c+x)/2)
    b.im = sqrt((c-x)/2)
    if a.im < 0:
        b.im = -b.im
    return b

# Wyświetla + przed
# liczbą dodatnią,
# '-' przed ujemną
# ------------------
def pl(x):
    if x >= 0:
        print("+", end="")
    else:
        print("-", end="")
    print(f"{abs(x):.3f}", end="")

# Wyświetlanie liczby
# zespolonej
def cmplx_print(a):
    pl(a.re)
    if abs(a.im) >= epsy:
        pl(a.im)
        print("i", end="")
    print()

# Funkcja rozwiązująca
# równanie sześcienne
# a,b,c,d - współczynniki
#           wielomianu
# cmplx - true, x1 = pierwiastek,
#               x2 = re,
#               x3 = +/- im
#      - false, x1,x2,x3 = pierwiastki
#               rzeczywiste
# x1,x2,x3 - pierwiastki
# ------------------------------------
def ce(a, b, c, d):
    # Znacznik wyniku
    # zespolonego
    cmpl = False

    # Modyfikujemy współczynniki
    # równania
    d /= a
    c /= a
    b /= a
    a = b
    b = c
    c = d

    # Obliczamy wyróżnik delta
    p = b-a*a/3
    q = 2*a*a*a/27-a*b/3+ c
    delta = p*p*p/27+q*q/4

    # Sprawdzamy przypadki
    if abs(delta) < epsy:
        # 3 pierwiastki, 2 podwójne
        sgn = (q > 0) - (q < 0)
        q = sgn*pow(abs(q)/2,1/3)
        x1 = -2*q-a/3
        x2 = q-a/3
        x3 = x2
    elif delta > 0:
        # 1 pierwiastek rzeczywisty,
        # 2 zespolone
        cmpl = True  # Wynik zespolony
        q /= -2
        delta = sqrt(delta)

        v1 = q + delta
        v2 = q - delta
        sgn1 = (v1 > 0) - (v1 < 0)
        sgn2 = (v2 > 0) - (v2 < 0)

        x1 = (sgn1*pow(abs(v1),1/3)
             +sgn2*pow(abs(v2),1/3)
             -a/3)

        # Schematem Hornera dzielimy
        # wielomian równania
        # sześciennego przez dwumian
        # (x - x1)
        aa = 1
        bb = a+aa*x1
        cc = b+bb*x1

        # Obliczamy wyróżnik
        # równania kwadratowego
        delta = bb*bb-4*aa* cc
        delta = sqrt(-delta)

        # Część rzeczywista
        x2 = -bb/2/aa
        # Część urojona
        x3 = delta/2/aa
    else:
        # 3 pierwiastki rzeczywiste
        a /= 3
        p  = sqrt(-p)
        pp = 2/sqrt(3)*p
        q  = 3*sqrt(3)*q/2/(p*p*p)
        x1 =  pp*sin(asin(q)/3)-a
        x2 = -pp*sin(asin(q)/3+pi/3)-a
        x3 =  pp*cos(asin(q)/3+pi/6)-a

    return cmpl, x1, x2, x3

# Funkcja rozwiązująca
# równanie czwartego stopnia
# a,b,c,d,e - współczynniki
#             wielomianu
# --------------------------
def qe(a, b, c, d, e):
    print("\nRównanie: ", end="")
    pl(a)
    print("*x^4", end="")
    pl(b)
    print("*x^3", end="")
    pl(c)
    print("*x^2", end="")
    pl(d)
    print("*x", end="")
    pl(e)
    print(" = 0")

    # Wyliczamy współczynniki
    f = (c-3*b*b/8/a)/a
    g = (d+b*b*b/8/a/a-b*c/2/a)/a
    h = (e-3*b*b*b*b/256/a/a/a
        +b*b*c/16/a/a-b*d/4/a)/a

    # Tworzymy pomocnicze równanie
    # sześcienne i wyliczamy jego
    # pierwiastki
    cmpl,x1,x2,x3 = ce(1,f/2,
                       (f*f-4*h)/16,
                       -g*g/64)
    y1 = cmplx()
    y2 = cmplx()
    # Pierwiastki zespolone
    if cmpl:
        y1.re = y2.re = x2
        y1.im = -x3
        y2.im = x3
    else:
        # Wybieramy dwa niezerowe
        # pierwiastki
        y1.im = y2.im = 0
        if abs(x1) < epsy:
            y1.re = x2
            y2.re = x3
        elif abs(x2) < epsy:
            y1.re = x1
            y2.re = x3
        else:
            y1.re = x1
            y2.re = x2

    # Obliczamy ich
    # pierwiastki zespolone
    u = cmplx()

    p = cmplx_sqrt(y1)
    q = cmplx_sqrt(y2)

    # Wyliczamy współczynniki s i r
    s = b/4/a
    t = cmplx_mul(p, q)
    u.re = -g/8.0
    u.im = 0
    r = cmplx_div(u, t)

    # Obliczamy pierwiastki
    # zespolone równania
    # czwartego stopnia
    r1 = cmplx()
    r2 = cmplx()
    r3 = cmplx()
    r4 = cmplx()

    r1.re = p.re+q.re+r.re-s
    r1.im = p.im+q.im+r.im

    r2.re = p.re-q.re-r.re-s
    r2.im = p.im-q.im-r.im

    r3.re = -p.re+q.re-r.re-s
    r3.im = -p.im+q.im-r.im

    r4.re = -p.re-q.re+r.re-s
    r4.im = -p.im-q.im+r.im

    # Wyświetlamy wyniki
    print("x1 = ", end="")
    cmplx_print(r1)
    print("x2 = ", end="")
    cmplx_print(r2)
    print("x3 = ", end="")
    cmplx_print(r3)
    print("x4 = ", end="")
    cmplx_print(r4)

# Program główny
# ---------------

print("Równania czwartego stopnia typu")
print("  4    3    2")
print("ax + bx + cx + dx + e = 0")
print("-------------------------------")

qe(1, -10, 35, -50, 24)
qe(1, -4, 3, 4, -4)
qe(1, 1, -7, -1, 6)
qe(5, 5, 5, 5, 5)

print()
input("Naciśnij Enter...")

do podrozdziału  do strony 

Równania wyższych stopni

Równanie stopnia czwartego jest ostatnim równaniem wielomianowym, dla którego istnieje algebraiczna metoda rozwiązywania. Udowodniono, że nie ma takiej metody dla równań o stopniu wyższym niż 4. Nie oznacza to oczywiście, że równania takie nie posiadają pierwiastków. Nie można jedynie znaleźć tych pierwiastków ogólną metodą o skończonej liczbie operacji. Pozostają nam zatem metody przybliżone lub metody rozwiązujące szczególne przypadki tych równań.

Do znalezienia rozwiązania z dowolną dokładnością można wykorzystać metodę Newtona oraz podział wielomianu schematem Hornera, gdy uda nam się znaleźć pierwiastek przybliżony. W efekcie otrzymamy równanie niższego stopnia. Korzystamy tutaj z tej samej procedury, którą stosowaliśmy dla równań 3-go i 4-go stopnia:

  1. Wyznaczamy punkty krytyczne.
  2. Porządkujemy wyznaczone punkty krytyczne rosnąco.
  3. Sprawdzamy, czy pierwiastek leży w jednym z punktów krytycznych. Jeśli tak, to przechodzimy do kroku 6.
  4. Sprawdzamy, czy w dwóch sąsiednich punktach krytycznych funkcja ma różne znaki. Jeśli tak, to pierwiastek znajduje się pomiędzy tymi punktami krytycznymi, znajdujemy go metodą Newtona i przechodzimy do kroku 6.
  5. Sprawdzamy, czy pierwiastek może być po lewej stronie pierwszego punktu krytycznego lub po prawej stronie ostatniego punktu krytycznego. Jeśli tak, to znajdujemy go metodą Newtona i przechodzimy do kroku 6. Jeśli nie, to równanie nie ma pierwiastków rzeczywistych i przerywamy obliczenia.
  6. Mamy wyznaczony pierwszy pierwiastek x1. Wielomian równania dzielimy za pomocą schematu Hornera przez dwumian (x - x1) i otrzymujemy równanie wynikowe o stopniu niższym o 1.
  7. Rozwiązujemy równanie wynikowe i otrzymujemy pełne rozwiązanie równania wyjściowego.

Zwróć uwagę, iż takie podejście pozwala rozwiązać równanie stopnia n, jeśli potrafimy rozwiązać równanie stopnia n - 1. Dodatkowo pamiętaj, iż równania o stopniach nieparzystych posiadają zawsze co najmniej jeden pierwiastek rzeczywisty.


do podrozdziału  do strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2026 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.