Serwis Edukacyjny
Nauczycieli I-LO

w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

Autor artykułu: mgr Jerzy Wałaszek

©2026 mgr Jerzy Wałaszek

W naszym serwisie jest nowszy artykuł o obliczaniu pierwiastków funkcji: "Metody numeryczne".

Metoda siecznych

SPIS TREŚCI
Podrozdziały

Algorytm

Mamy daną funkcję \(f(x)\), dwa punkty startowe \(x_1\) oraz \(x_2\) i przedział \({[a,b]}\) poszukiwań pierwiastka, do którego należą punkty \(x_1\) i \(x_2.\) W przedziale poszukiwań pierwiastka funkcja musi spełniać następujące warunki:

\[
{f(a)<f(x_0)=0<f(b)} \text{ lub } {f(a)>f(x_0)=0>f(b)}
\]

Gdy funkcja \(f(x)\) spełnia podane warunki, to w przedziale \({[a,b]}\) istnieje pierwiastek i możemy go wyszukać metodą siecznych.

Metoda siecznych (ang. secant method) jest ulepszeniem metody regula falsi. W metodzie regula falsi żądamy, aby funkcja \(f(x)\) zawsze przyjmowała różne znaki na krańcach przedziału poszukiwań pierwiastka. Różne znaki gwarantują nam istnienie pierwiastka w tym przedziale. Otóż w metodzie siecznych taki wymóg nie jest konieczny (za wyjątkiem pierwszego obiegu). Do wyznaczenia kolejnego przybliżenia pierwiastka funkcji wykorzystujemy dwa poprzednio wyznaczone punkty:

\[
x_i=x_{i-1}-f(x_{i-1})\cdot \dfrac{x_{i-1}-x_{i-2}}{f(x_{i-1})-f(x_{i-2})}
\]

Okazuje się, iż takie podejście do problemu znacznie przyspiesza znajdowanie pierwiastka funkcji. Prześledźmy graficznie tok postępowania:

Za początkowe punkty \(x_1\) i \(x_2\) przyjmujemy punkty krańcowe przedziału poszukiwań pierwiastka. Ponieważ funkcja zmienia znak w tym przedziale i jest określona oraz ciągła, mamy gwarancję istnienia pierwiastka. Z punktów wykresu funkcji dla \(x_1\) i \(x_2\) prowadzimy sieczną – na rysunku zaznaczoną kolorem zielonym. Punkt przecięcia się tej siecznej z osią OX daje nam następny punkt \(x_3\).

Drugą sieczną prowadzimy z punktów wykresu funkcji dla \(x_2\) oraz \(x_3\). Otrzymujemy punkt \(x_4\).

Trzecia sieczna prowadzona jest z punktów wykresu funkcji dla \(x_3\) i \(x_4\). Otrzymujemy kolejny punkt \(x_5\). Już widać, iż leży on bardzo blisko rzeczywistego pierwiastka funkcji.

Ostatnią sieczną prowadzimy z punktów wykresu funkcji dla \(x_4\) i \(x_5\). Otrzymany punkt \(x_6\) jest już dostatecznie blisko pierwiastka funkcji. Zwróć uwagę, iż kolejne punkty \(x_i\) zbliżają się do siebie.

Jeśli punkty początkowe \(x_1\), \(x_2\) zostaną źle dobrane, to algorytm może nie dać rozwiązania. Dlatego stosujemy w nim dodatkowy licznik obiegów pętli wyznaczającej kolejne przybliżenia pierwiastka funkcji. Jeśli po wykonaniu zadanej liczby obiegów (u nas \(64\)) nie zostanie znalezione rozwiązanie, to algorytm przerywa obliczenia z odpowiednim komunikatem. Obliczenia również będą przerwane w przypadku, gdy algorytm stwierdzi, iż sieczna jest równoległa do osi OX. Poprawnym warunkiem zakończenia algorytmu jest:

\[
|x_{i-1}-x_{i-2}|<\varepsilon_x\text{ lub }|f(x_i)|<\varepsilon_0
\]

do podrozdziału  do strony 

Opis algorytmu

Specyfikacja problemu

Dane wejściowe

\(f(x)\)

 
–

 
funkcja rzeczywista, której pierwiastek
liczymy. Musi być ciągła i określona
w przedziale poszukiwań pierwiastka.
\(x_1, x_2\)



 
–



 
punkty krańcowe przedziału poszukiwań
pierwiastka funkcji \(f(x)\). W dalszej fazie
obliczeń punkty te przechowują dwie
poprzednie wartości \(x_0\) - \(x_1\) ostatnią,
a \(x_2\) przedostatnią; \({x_1, x_2\in\mathbb{R}}\).

Dane wyjściowe

\(x_0\) – pierwiastek funkcji \(f(x)\); \({x_0\in\mathbb{R}}\).

Zmienne pomocnicze i funkcje

\(f_0, f_1, f_2\)
 
–
 
wartości funkcji odpowiednio
w punktach \(x_0, x_1, x_2\); \({f_0, f_1, f_2\in\mathbb{R}}\).
\(i\)

 
–

 
licznik obiegów pętli. Obiegi są
zliczane wstecz od wartości \(i = 64\);
\(i\in\mathbb{Z}\).
\(\varepsilon_0\)
 
–
 
określa dokładność porównania
z zerem; \(\varepsilon_0 = 0{,}0000000001\).
\(\varepsilon_x\)
 
–
 
określa dokładność wyznaczania
pierwiastka \(x_0\); \(\varepsilon_x = 0{,}0000000001\).

Lista kroków

  K01: Czytaj \(x_1, x_2\)
  K02: \(f_1\leftarrow f(x_1)\); \(f_2\leftarrow f(x_2)\); \(i\leftarrow 64\)
  K03: Dopóki \((i > 0) \wedge (|x_1 - x_2| > \varepsilon_x):\)
wykonuj kroki K04...K08
K04:     Jeśli \(|f_1 - f_2 | < \varepsilon_0,\)
    to pisz "Złe punkty startowe"
    i zakończ
K05: \({x_0\leftarrow x_1-f_1\cdot\dfrac{x_1-x_2}{f_1-f_2};\;f_0\leftarrow f(x_0)}\)
K06:     Jeśli \(|f_0| < \varepsilon_0,\) 
    to idź do kroku K10
K07:  \(\begin{array}{l}x_2\leftarrow x_1;\;f_2\leftarrow f_1;\\
 x_1\leftarrow x_0;\;f_1\leftarrow f_0\end{array}\)
K08:     \(i\leftarrow i - 1\)
  K09: Jeśli \(i = 0\),
to pisz "Przekroczony limit obiegów"
i zakończ
  K10: Pisz \(x_0\)
i zakończ

Schemat blokowy

obrazek

Wykonanie algorytmu siecznych rozpoczynamy od odczytu dwóch punktów \(x_1\) oraz \(x_2\). Punkty te posłużą do wyznaczenia pierwszej siecznej. Nie muszą one obejmować przedziału, w którym funkcja zmienia znak, jednakże jest to wskazane.

Dla obu punktów obliczamy wartości funkcji umieszczając je w zmiennych odpowiednio \(f_1\) i \(f_2\). Ponieważ algorytm siecznych może nie dać rozwiązania, stosujemy proste zabezpieczenie w postaci zliczania wykonanych obiegów pętli. Zmienna \(i\) pełni rolę licznika tych obiegów. Obiegi zliczane są wstecz. Na początku w zmiennej \(i\) określamy maksymalną ilość obiegów, po których algorytm zaprzestanie wykonywać obliczenia pierwiastka.

Rozpoczynamy pętlę obliczającą kolejne przybliżenia pierwiastka funkcji. Pętla kończy się w jednym z trzech przypadków:

  1. Licznik \(i\) osiąga zero - wypisujemy odpowiedni komunikat i kończymy algorytm – pierwiastek nie został znaleziony, a \(x_0\) zawiera zwykle jakieś przypadkowe wartości. Jest to sygnał, iż początkowe punkty \(x_1\) i \(x_2\) były zbyt odległe od pierwiastka funkcji.
  2. Ostatnie dwa pierwiastki przybliżone \(x_1\) i \(x_2\) różnią się od siebie o mniej niż \(\varepsilon_x\) – w takim przypadku \(x_0\) jest przybliżonym pierwiastkiem. Wypisujemy \(x_0\) i kończymy algorytm.
  3. Moduł różnicy wartości funkcji \(f_1\) i \(f_2\) dla dwóch ostatnich pierwiastków \(x_1\) i \(x_2\) jest równy zero. Ponieważ różnica ta występuje w mianowniku ułamka we wzorze obliczającym nowy pierwiastek \(x_0\), musimy przerwać obliczenia. Wypisujemy odpowiedni komunikat i kończymy algorytm.

Na początku pętli wyznaczamy nowe przybliżenie pierwiastka \(x_0\) oraz wartość funkcji w tym punkcie \(f_0\). Do wyznaczenia \(x_0\) stosujemy wzór siecznych, który wykorzystuje dwa ostatnio wyliczone przybliżenia pierwiastka \(x_1\) i \(x_2\).

Jeśli \(f_0\) jest dostatecznie bliskie zeru, to \(x_0\) jest przybliżonym pierwiastkiem, wypisujemy \(x_0\) i kończymy algorytm.

W przeciwnym razie przesuwamy \(x_1\) i \(x_0\) odpowiednio do \(x_2\) i \(x_1\) wraz z wartościami funkcji w tych punktach i kontynuujemy pętlę. Przesunięcie wartości funkcji \(f_1\) i \(f_0\) zwalnia nas od konieczności ich ponownego wyliczania.


do podrozdziału  do strony 

Programy

Programy wyznaczają miejsce zerowe funkcji:

\[
f(x)=x^3\cdot\left(x+\sin(x^2-1)-1\right)-1
\]

Pierwiastków należy poszukiwać w przedziałach \({[-1;0]}\) i \({[1;2]}\).

C++
// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu
// siecznych
// ------------------------
//  (C)2006 mgr J.Wałaszek

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdlib>

using namespace std;

// dokładność porównania z zerem
const double EPS0 = 0.0000000001;
// dokładność wyznaczenia pierwiastka
const double EPSX = 0.0000000001;

// Funkcja, której miejsce zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
//-----------------------------------------

double f(double x)
{
  return x * x * x * (x + sin(x * x - 1)
         - 1) - 1;
}

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

int main()
{

  double x0,x1,x2,f0,f1,f2;
  int    i;

  cout << setprecision(8)
       << fixed

       << "Obliczanie pierwiastka funkcji\n"
          "       Metoda Siecznych\n"
          "f(x) =  x^3*(x+sin(x^2-1)-1)-1\n"
          "------------------------------\n"
          "  (C)2006 mgr Jerzy Walaszek\n\n"
          "Podaj dwa wstepne punkty x1 i x2:\n\n";
  cout << "x1 = "; cin >> x1;
  cout << "x2 = "; cin >> x2;
  cout << "\nWYNIK:\n\n";
  f1 = f(x1);
  f2 = f(x2);
  i = 64;
  while(i && (fabs(x1 - x2) > EPSX))
  {
    if(fabs(f1 - f2) < EPS0)
    {
      cout << "Zle punkty startowe\n";
      i = 0;
      break;
    }
    x0 = x1 - f1 * (x1 - x2) / (f1 - f2);
    f0 = f(x0);
    if(fabs(f0) < EPS0) break;
    x2 = x1; f2 = f1;
    x1 = x0; f1 = f0;
    if(!(--i))
      cout << "Przekroczony limit obiegow\n";
  }
  if(i)
    cout << "x0 = "
         << setw(15) << x0 << endl;
  cout << "\n\n";
  system("pause");
  return 0;
}
Pascal
// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu
// siecznych
// ------------------------
//  (C)2006 mgr J.Wałaszek

program mzf1;

uses math;

const
  // dokładność porównania z zerem
  EPS0 = 0.0000000001;
  // dokładność wyznaczenia pierwiastka
  EPSX = 0.0000000001;

// Funkcja, której miejsce zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
//-----------------------------------------
function f(x : real) : double;
begin
  Result := x * x * x * (x + sin(x * x -
            1) - 1) - 1;
end;

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

var
  x0,x1,x2,f0,f1,f2 : double;
  i                 : integer;

begin
  writeln('Obliczanie pierwiastka funkcji');
  writeln('       Metoda Siecznych');
  writeln('f(x) =  x^3*(x+sin(x^2-1)-1)-1');
  writeln('------------------------------');
  writeln('  (C)2006 mgr Jerzy Walaszek');
  writeln;
  writeln('Podaj dwa wstepne punkty x1 i x2:');
  writeln;
  write('x1 = '); readln(x1);
  write('x2 = '); readln(x2);
  writeln;
  writeln('WYNIK:');
  writeln;
  f1 := f(x1);
  f2 := f(x2);
  i  := 64;
  while (i > 0) and
        (abs(x1 - x2) > EPSX) do
  begin
    if abs(f1 - f2) < EPS0 then
    begin
      writeln('Zle punkty startowe');
      i := 0;
      break;
    end;
    x0 := x1 - f1 * (x1 - x2) / (f1 - f2);
    f0 := f(x0);
    if abs(f0) < EPS0 then break;
    x2 := x1; f2 := f1;
    x1 := x0; f1 := f0;
    dec(i);
    if i = 0 then
      writeln('Przekroczony limit obiegow');
  end;
  if i > 0 then writeln('x0 = ',x0:15:8);
  writeln;
  writeln('Nacisnij Enter...');
  readln;
end.
Basic
' Program znajduje miejsce
' zerowe funkcji f(x)
' za pomocą algorytmu
' siecznych
'-------------------------
' (C)2006 mgr J.Wałaszek

Declare Function f(ByVal x _
                   As Double) _
                   As Double

' dokładność porównania z zerem
Const EPS0 As Double = 0.0000000001
' dokładność wyznaczenia pierwiastka
Const EPSX As Double = 0.0000000001

'---------------
' Program główny
'---------------

Dim As double x0, x1, x2, f0, f1, f2
Dim i As Integer

Print "Obliczanie pierwiastka funkcji"
Print "       Metoda Siecznych"
Print "f(x) =  x^3*(x+sin(x^2-1)-1)-1"
Print "------------------------------"
Print "  (C)2006 mgr Jerzy Walaszek"
Print
Print "Podaj dwa wstepne punkty x1 i x2:"
Print
Input "x1 = ", x1
Input "x2 = ", x2
Print
Print "WYNIK:"
Print

f1 = f(x1)
f2 = f(x2)
i  = 64

While (i > 0) And (Abs(x1 - x2) > EPSX)
  If Abs(f1 - f2) < EPS0 Then
    Print "Zle punkty startowe"
    i = 0
    Exit While
  End If
  x0 = x1 - f1 * (x1 - x2) / (f1 - f2)
  f0 = f(x0)
  If Abs(f0) < EPS0 Then Exit While
  x2 = x1 : f2 = f1
  x1 = x0 : f1 = f0
  i -= 1
  If i = 0 Then _
    Print "Przekroczony limit obiegow"
Wend

If i > 0 Then _
  Print Using "x0 = ######.########"; x0
Print
Print "Nacisnij Enter..."
Sleep
End

' Funkcja, której miejsce
' zerowe obliczamy
' f(x) = x^3*(x+sin(x^2-1)-1)-1
' <-1,0> i <1,2>
'------------------------------
Function f(ByVal x As Double) _
                   As Double
   Return x * x * x * _
         (x + Sin(x * x - 1) - 1) - 1
End Function
Python (dodatek)
# Program znajduje miejsce
# zerowe funkcji f(x)
# za pomocą algorytmu
# siecznych
#-------------------------
# (C)2006 mgr J.Wałaszek

import math

# Funkcja, której miejsce
# zerowe obliczamy
# f(x) = x^3*(x+sin(x^2-1)-1)-1
# <-1,0> i <1,2>
def f(x):
        return x * x * x * \
                     (x+math.sin(x*x-1)-1)-1

# dokładność porównania z zerem
EPS0 = 0.0000000001
# dokładność wyznaczenia pierwiastka
EPSX = 0.0000000001

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

print("Obliczanie pierwiastka funkcji")
print("       Metodą Siecznych")
print("f(x) =  x^3*(x+sin(x^2-1)-1)-1")
print("------------------------------")
print("  (C)2026 mgr Jerzy Wałaszek")
print()
print("Podaj dwa wstępne punkty x1 i x2:")
print()
x1 = float(input("x1 = "))
x2 = float(input("x2 = "))
print()
print("WYNIK:")
print()

f1 = f(x1)
f2 = f(x2)
i  = 64
while (i > 0) and \
      (abs(x1 - x2) > EPSX):
    if abs(f1 - f2) < EPS0:
        print("Złe punkty startowe")
        i = 0
        break
    x0 = x1-f1*(x1-x2)/(f1-f2)
    f0 = f(x0)
    if abs(f0) < EPS0: break
    x2, f2 = x1, f1
    x1, f1 = x0, f0
    i -= 1
    if not i:
        print("Przekroczony limit obiegów")

if i > 0:
    print("x0 = %15.8f" % x0)
print()
input("Naciśnij Enter...")
Wynik:
Obliczanie pierwiastka funkcji
       Metodą Siecznych
f(x) =  x^3*(x+sin(x^2-1)-1)-1
------------------------------
  (C)2026 mgr Jerzy Wałaszek

Podaj dwa wstępne punkty x1 i x2:

x1 = 1
x2 = 2

WYNIK:

x0 =      1.18983299

Naciśnij Enter...
JavaScript
<html>
  <head>
  </head>
  <body>
<div style="overflow-x: auto; overflow-y: hidden;"
     align="center">
  <table
  border="0"
  cellpadding="4"
  style="border-collapse:
         collapse">
    <tr>
      <td nowrap>
        <form
        name="frmbincode"
        style="text-align: center;
               background-color:
               #E7E7DA;">
          <b><big>
          Obliczanie<br>
          pierwiastka funkcji<br>
          metodą Siecznych
          </big></b><br><br>
          f(x) = x<sup>3</sup>(x +
          sin(x<sup>2</sup>-1)-1)-1<br>
          <br>
          &nbsp;&nbsp;
          (C)2026
          mgr Jerzy Wałaszek
          I LO w Tarnowie
          &nbsp;&nbsp;
          <hr>
          Wpisz do pól edycyjnych<br>
          dwa punkty startowe<br>
          <br>
          x<sub>1</sub> =
          <input
          type="text"
          name="inp_x1"
          size="16"
          value="1"
          style="text-align:
                 right">
          <br>
          x<sub>2</sub> =
          <input
          type="text"
          name="inp_x2"
          size="16"
          value="2"
          style="text-align:
                 right">
          <hr>
          <input
          type="button"
          value="Szukaj"
          name="B1"
          onclick="main()">
          <hr>
          <b>Wynik:</b>
          <div id="out">.</div>
        </form>
      </td>
    </tr>
  </table>
</div>

<script language=javascript>

// Program znajduje miejsce
// zerowe funkcji f(x)
// za pomocą algorytmu siecznych
//------------------------------
// (C)2006 mgr J.Wałaszek
// I LO w Tarnowie

// dokładność porównania
// z zerem
var EPS0 = 0.0000000001
// dokładność wyznaczenia
// pierwiastka
var EPSX = 0.0000000001

// Funkcja, której miejsce
// zerowe obliczamy
// f(x) = x^3*(x+sin(x^2-1)-1)-1
// <-1,0> i <1,2>
function f(x)
{
  return x * x * x *
        (x + Math.sin(x *
         x - 1) - 1) - 1
}

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

function main()
{

  var x0,x1,x2,f0,f1,f2,i,t

  x1 = parseFloat(document
      .frmbincode.inp_x1.value)
  x2 = parseFloat(document
      .frmbincode.inp_x2.value)
  if(isNaN(x1) || isNaN(x2))
    t = "<font color=red><b>" +
        "Nieprawidłowe dane!" +
        "</b></font>"
  else  
  {
    f1 = f(x1)
    f2 = f(x2)
    i = 64 // limit obiegów
    while(i &&
         (Math.abs(x1 - x2)
         > EPSX))
    {
      if(Math.abs(f1 - f2) < EPS0)
      {
        t = "<font color=red><b>" +
            "Złe punkty startowe!" +
            "</b></font>"
        i = 0;
        break;
      }
      x0 = x1 - f1 * (x1 - x2) /
          (f1 - f2)
      f0 = f(x0)
      if(Math.abs(f0) < EPS0)
        break
      x2 = x1
      f2 = f1
      x1 = x0
      f1 = f0
      if(!(--i))
       t = "<font color=red><b>" +
           "Przekroczony limit obiegów!" +
           "</b></font>";
    }
    if(i) t = "x<sub>0</sub> = " + x0
  }
  document.getElementById("out")
  .innerHTML = t
}

</script>
  </body>
</html>

Tutaj możesz przetestować działanie prezentowanego skryptu. Przykładowa funkcja posiada pierwiastki w  przedziałach \({[-1;0]}\) i \({[1;2]}\).

Obliczanie
pierwiastka funkcji
metodą Siecznych


f(x) = x3(x + sin(x2-1)-1)-1

   (C)2026 mgr Jerzy Wałaszek I LO w Tarnowie   
Wpisz do pól edycyjnych
dwa punkty startowe

x1 =
x2 =

Wynik:
.

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.