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 x1 oraz x2 i przedział a;b poszukiwań pierwiastka, do którego należą punkty x1, x2. W przedziale poszukiwań pierwiastka funkcja musi spełniać następujące warunki:

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:

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

obrazek Za początkowe punkty x1 i x2 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 x1 i x2
prowadzimy sieczną - na rysunku
zaznaczoną kolorem czerwonym. Punkt
przecięcia się tej siecznej z osią OX daje
nam następny punkt x3.

obrazek Drugą sieczną prowadzimy z punktów
wykresu funkcji dla x2 oraz x3.
Otrzymujemy punkt x4.
obrazek Trzecia sieczna prowadzona jest
z punktów wykresu funkcji dla x3 i x4.
Otrzymujemy kolejny punkt x5. Już
widać, iż leży on bardzo blisko
rzeczywistego pierwiastka funkcji.
obrazek Ostatnią sieczną prowadzimy
z punktów wykresu funkcji dla x4 i x5.
Otrzymany punkt x6 jest już
dostatecznie blisko pierwiastka
funkcji. Zwróć uwagę, iż kolejne
punkty xi zbliżają się do siebie.

Jeśli punkty początkowe x1, x2 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:

 


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.
x1, x2 punkty krańcowe przedziału poszukiwań
pierwiastka funkcji f(x). W dalszej fazie
obliczeń punkty te przechowują dwie
poprzednie wartości xo - x1 ostatnią,
a x2 przedostatnią; x1, x2R.

Dane wyjściowe

xo pierwiastek funkcji f(x); xoR.

Zmienne pomocnicze i funkcje

fo, f1 , f2 wartości funkcji odpowiednio
w punktach xo, x1, x2; fo, f1, f2R.
i licznik obiegów pętli. Obiegi są
zliczane wstecz od wartości i = 64;
i ∈ C
εo określa dokładność porównania
z zerem; εo = 0.0000000001.
εx określa dokładność wyznaczania
pierwiastka xo; εx = 0.0000000001.

Lista kroków

  K01: Czytaj x1 i x2
  K02: f1 ← f(x1); f2 ← f(x2); i ← 64
  K03: Dopóki (i > 0) ∧ (| x1 - x2 | > εx):
wykonuj kroki K04...K08
K04:     Jeśli | f1 - f2 | < εo,
    to pisz "Złe punkty startowe"
    i zakończ
K05:
K06:     Jeśli | fo | < εo
    to idź do kroku K10
K07:     x2 ← x1; f2 ← f1;
    x1 ← xo; f1 ← fo
K08:     i ← i - 1
  K09: Jeśli i = 0,
to pisz "Przekroczony limit obiegów"
i zakończ
  K10: Pisz xo
i zakończ

Schemat blokowy

obrazek

Wykonanie algorytmu siecznych rozpoczynamy od odczytu dwóch punktów x1 oraz x2. 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 f1 i f2. 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 xo zawiera zwykle jakieś przypadkowe wartości. Jest to sygnał, iż początkowe punkty x1 i x2 były zbyt odległe od pierwiastka funkcji.
  2. Ostatnie dwa pierwiastki przybliżone x1 i x2 różnią się od siebie o εx lub mniej - w takim przypadku xo jest przybliżonym pierwiastkiem. Wypisujemy xo i kończymy algorytm.
  3. Moduł różnicy wartości funkcji f1 i f2 dla dwóch ostatnich pierwiastków x1 i x2 jest równy zero. Ponieważ różnica ta występuje w mianowniku ułamka we wzorze obliczającym nowy pierwiastek xo, musimy przerwać obliczenia. Wypisujemy odpowiedni komunikat i kończymy algorytm.

Na początku pętli wyznaczamy nowe przybliżenie pierwiastka xo oraz wartość funkcji w tym punkcie fo. Do wyznaczenia xo stosujemy wzór siecznych, który wykorzystuje dwa ostatnio wyliczone przybliżenia pierwiastka x1 i x2.

Jeśli fo jest dostatecznie bliskie zeru, to xo jest przybliżonym pierwiastkiem, wypisujemy xo i kończymy algorytm.

W przeciwnym razie przesuwamy x1 i xo odpowiednio do x2 i x1 wraz z wartościami funkcji w tych punktach i kontynuujemy pętlę. Przesunięcie wartości funkcji f1 i fo zwalnia nas od konieczności ich ponownego wyliczania.


do podrozdziału  do strony 

Programy

Programy wyznaczają miejsce zerowe funkcji:

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;"
     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.