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 połowienia

SPIS TREŚCI
Podrozdziały

Algorytm

Mamy daną funkcję f(x) oraz przedział ⟨a;b⟩, w którym będziemy poszukiwali miejsca zerowego (czyli pierwiastka funkcji f(x)). Aby można było zastosować algorytm połowienia (zwany również algorytmem bisekcji), w przedziale ⟨a;b⟩ muszą być spełnione poniższe warunki:

  1. Funkcja f(x) jest określona - uczniowie często nie rozumieją tego pojęcia. Określoność funkcji oznacza, iż dla każdej wartości argumentu x z przedziału ⟨a;b⟩ potrafimy policzyć wartość funkcji. W trakcie pracy algorytm połowienia oblicza wartości funkcji dla argumentów należących do tego przedziału ⟨a;b⟩. Jeśli przypadkowo trafi na punkt, dla którego wartość funkcji jest nieokreślona, obliczenia się załamią. W praktyce konsekwencje mogą być tragiczne, np. zmiana lotu samolotu z poziomego na pionowy w kierunku ziemi...

    Dla przykładu rozważmy prostą funkcję:
    Ile wynosi wartość tej funkcji dla x = 1? Musimy dzielić przez 0, a jak wiadomo jest to zadanie niewykonalne. W punkcie x = 1 tak podana funkcja ma nieokreśloną wartość. Co gorsza punkt ten wypada akurat w środku przedziału ⟨a;b⟩ i algorytm bisekcji trafi na niego przy pierwszym obiegu.
  2. Funkcja f(x) jest ciągła. Ciągłość funkcji oznacza z kolei, iż jej wartości nie "wykonują" nagłych skoków. Funkcja przebiega przez wszystkie wartości pośrednie - nie istnieją zatem przerwy w kolejnych wartościach funkcji. Dla przykładu rozważmy taką oto funkcję:
    Funkcja w przedziale ⟨-2;1⟩ posiada następujący wykres:
    obrazek
    Nieciągłość występuje w punkcie x = 0, czyli w miejscu zmiany przepisu funkcji. Zwróć uwagę, iż funkcja jest określona w tym punkcie - nieciągłość i nieokreśloność to dwie różne sprawy - nie myl ich!!!
  3. Funkcja f(x) na krańcach przedziału ⟨a;b⟩ przyjmuje różne znaki. Ponieważ funkcja, zgodnie z poprzednim podpunktem, jest ciągła, to przyjmuje w przedziale ⟨a;b⟩, wszystkie wartości pośrednie pomiędzy f(a) i f(b). Wartości te mają różne znaki (czyli leżą po różnych stronach osi OX), zatem musi być taki punkt x0 w przedziale ⟨a;b⟩, dla którego funkcja przyjmuje wartość pośrednią:
    Gdy funkcja f(x) spełnia powyższe trzy warunki, to w przedziale ⟨a;b⟩ zagwarantowane jest istnienie pierwiastka i możemy go wyszukać algorytmem połowienia (bisekcji). Zasada jest następująca:
    Wyznaczamy punkt x0 jako środek przedziału ⟨a;b⟩ zgodnie ze wzorem:
    Obliczamy wartość funkcji w punkcie x0. Jeśli długość przedziału jest mniejsza od założonej dokładności wyliczeń pierwiastka, to wartość x0 jest poszukiwanym przybliżeniem. Kończymy algorytm. W przeciwnym razie sprawdzamy, czy f(x0) znajduje się dostatecznie blisko 0:
    Jeśli nierówność jest spełniona, to x0 jest poszukiwaną wartością pierwiastka. Zwracamy wynik i kończymy algorytm. W przeciwnym razie za nowy przedział poszukiwań pierwiastka przyjmujemy tą połówkę ⟨a;x0⟩ lub ⟨x0;b⟩,, w której funkcja zmienia znak na krańcach. Algorytm powtarzamy od początku dotąd, aż znajdziemy pierwiastek lub przedział ⟨a;b⟩ osiągnie założoną długość (może to być również epsilon). Wtedy kończymy zwracając ostatnio wyliczone x0.

do podrozdziału  do strony 

Opis algorytmu

Specyfikacja problemu

Dane wejściowe

f(x) – funkcja, której pierwiastek liczymy.
Musi być ciągła i określona w przedziale
poszukiwań pierwiastka.
a,b – punkty krańcowe przedziału poszukiwań
pierwiastka funkcji f(x); a,b ∈ R

Dane wyjściowe

x0 – pierwiastek funkcji f(x)

Zmienne pomocnicze i funkcje

fa , fb, f0 – wartości funkcji odpowiednio
w punktach a, b, x0; fa, fb, f0 ∈ R
ε0 – określa dokładność porównania
z zerem; ε0 = 0.0000000001
εx – określa dokładność wyznaczania
pierwiastka x0; εx = 0.0000000001

Lista kroków

  K01: Czytaj a i b
  K02: fa ← f(a) ; fb ← f(b)
  K03: Jeśli fa · fb > 0,
to pisz
"Brak pierwiastka"
i zakończ
  K04: Dopóki | a - b | > εx:
wykonuj kroki
K05...K07
K05:
K06:     Jeśli | f0 | < ε0,
    to idź do kroku K08
K07:     Jeśli fa · f0 < 0,
    to  b ← x0
    inaczej  a ← x0;   fa ← f0
  K08: Pisz x0
i zakończ

Schemat blokowy

obrazek

Wykonanie algorytmu rozpoczynamy od odczytu zakresu poszukiwań pierwiastka danej funkcji. W zmiennych fa i fb umieszczamy wartość funkcji na krańcach tego zakresu

Pierwszy test ma na celu sprawdzenie warunku różnych znaków wartości funkcji na krańcach zakresu poszukiwań pierwiastka. Różne znaki gwarantują nam istnienie pierwiastka w danym przedziale poszukiwań. Zatem jeśli funkcja na krańcach nie przybiera różnych znaków, wypisujemy odpowiedni komunikat i kończymy algorytm.

Rozpoczynamy pętlę wyliczania kolejnych przybliżeń pierwiastka funkcji. Pętla wykonuje się do momentu, aż przedział poszukiwań pierwiastka osiągnie długość εx.

Wewnątrz pętli wyznaczamy punkt x0 leżący w środku przedziału ⟨a;b⟩ oraz obliczamy wartość funkcji w punkcie x0 i umieszczamy ją w zmiennej f0. Jeśli wartość f0 jest dostatecznie bliska zeru (wpada w otoczenie zera o promieniu ε0), przerywamy pętlę, wypisujemy x0 i kończymy algorytm.

W przeciwnym razie za nowy przedział ⟨a;b⟩ przyjmujemy połówkę wyznaczoną przez x0, w której funkcja zmienia znak. Testujemy iloczyn fa przez f0. Jeśli iloczyn jest ujemny, to różne znaki funkcja przyjmuje w połówce ⟨a;b⟩. Zatem za nowy koniec b przyjmujemy x0 i kontynuujemy pętlę. W przeciwnym razie zmiana znaku występuje w drugiej połówce przedziału - ⟨a;b⟩. Za nowy początek a przyjmujemy x0. Dodatkowo za fa przyjmujemy f0 - zwolni nas to od konieczności ponownego wyliczania wartości funkcji w nowym punkcie a. Po tych czynnościach kontynuujemy pętlę wyznaczania kolejnych przybliżeń pierwiastka x0.


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
// połowienia - bisekcji
// ------------------------
//  (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 a,b,x0,fa,fb,f0;

  cout << setprecision(5)
       << fixed
       << "Obliczanie pierwiastka funkcji\n"
       << "       metoda bisekcji\n"
       << "f(x) = x^3*(x+sin(x^2-1)-1)-1\n"
       << "------------------------------\n"
       << "  (C)2006 mgr Jerzy Walaszek\n\n"
       << "Podaj przedział poszukiwania:\n\n";
  cout << "a = "; cin >> a;
  cout << "b = "; cin >> b;
  cout << "\nWYNIK:\n\n";
  fa = f(a); fb = f(b);
  if(fa * fb > 0)
    cout << "Brak pierwiastka\n";
  else
  {
    while(fabs(a - b) > EPSX)
    {
      x0 = (a + b) / 2; f0 = f(x0);
      if(fabs(f0) < EPS0) break;
      if(fa * f0 < 0) b = x0;
      else
      {
        a = x0; fa = f0;
      }
    }
    cout << "x0 = "
         << setw(15) << x0 << endl;
  }
  cout << endl;
  system("pause");
  return 0;
}
Pascal
// Program znajduje miejsce
// zerowe funkcji f(x) za
// pomocą algorytmu
// połowienia - bisekcji
// ------------------------
//  (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
  f := x * x * x * (x +
       sin(x * x - 1) - 1) - 1;
end;

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

var
  a,b,x0,fa,fb,f0 : double;

begin
  writeln('Obliczanie pierwiastka funkcji');
  writeln('       metoda bisekcji');
  writeln('f(x) = x^3*(x+sin(x^2-1)-1)-1');
  writeln('------------------------------');
  writeln('  (C)2006 mgr Jerzy Walaszek');
  writeln;
  writeln('Podaj przedzial poszukiwania:');
  writeln;
  write('a = '); readln(a);
  write('b = '); readln(b);
  writeln;
  writeln('WYNIK:');
  writeln;
  fa := f(a); fb := f(b);
  if fa * fb > 0 then
    writeln('Brak pierwiastka')
  else
  begin
    while abs(a - b) > EPSX do
    begin
      x0 := (a + b) / 2; f0 := f(x0);
      if abs(f0) < EPS0 then break;
      if fa * f0 < 0 then b := x0
      else
      begin
        a := x0; fa := f0;
      end;
    end;
    writeln('x0 = ',x0:15:8);
  end;
  writeln;
  writeln('Nacisnij Enter...');
  readln;
end.
Basic
' Program znajduje miejsce
'  zerowe funkcji f(x) za
'     pomocą algorytmu
'  połowienia  - bisekcji
' ------------------------
'  (C)2006 mgr J.Wałaszek

Declare Function f(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 a, b, x0, fa, fb, f0

Print "Obliczanie pierwiastka funkcji"
Print "       metoda bisekcji"
Print "f(x) = x^3*(x+sin(x^2-1)-1)-1"
Print "------------------------------"
Print "  (C)2006 mgr Jerzy Walaszek"
Print
Print "Podaj przedzial poszukiwania:"
Print
Input "a = ", a
Input "b = ", b
Print
Print "WYNIK:"
Print
fa = f(a) : fb = f(b)
If fa * fb > 0 Then
  Print "Brak pierwiastka"
Else
  While Abs(a - b) > EPSX
    x0 = (a + b) / 2 : f0 = f(x0)
    If Abs(f0) < EPS0 Then Exit While
    If fa * f0 < 0 Then
      b = x0
    Else
      a = x0 : fa = f0
    End If
  Wend
  Print Using "x0 = ######.########"; x0
End If
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(x As Double) As Double
  f = x*x*x*(x+Sin(x*x-1)-1)- 1
End Function
Python (dodatek)
# Program znajduje miejsce
#  zerowe funkcji f(x) za
#     pomocą algorytmu
#  połowienia  - bisekcji
# ------------------------
#  (C)2026 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("       metoda bisekcji")
print("f(x) = x^3*(x+sin(x^2-1)-1)-1")
print("------------------------------")
print("  (C)2026 mgr Jerzy Wałaszek")
print()
print("Podaj przedział poszukiwania:")
print()
a = float(input("a = "))
b = float(input("b = "))
print()
print("WYNIK:")
print()
fa, fb = f(a), f(b)
if fa * fb > 0:
    print("Brak pierwiastka")
else:
    while abs(a - b) > EPSX:
        x0 = (a + b) / 2
        f0 = f(x0)
        if abs(f0) < EPS0: break
        if fa * f0 < 0:
            b = x0
        else:
            a, fa = x0, f0
    print("x0 = %15.8f" % x0)
print()
input("Naciśnij Enter...")
Wynik:
Obliczanie pierwiastka funkcji
       metoda bisekcji        
f(x) = x^3*(x+sin(x^2-1)-1)-1 
------------------------------
  (C)2026 mgr Jerzy Wałaszek  

Podaj przedział poszukiwania: 

a = 1
b = 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ą Bisekcji
          </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>
          krańce przedziału<br>
          poszukiwań pierwiastka<br>
          <br>
          a = <input
              type="text"
              name="inp_a"
              size="16"
              value="1"
              style="text-align:
              right">
          <br>
          b = <input
              type="text"
              name="inp_b"
              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
// połowienia - bisekcji
//----------------------
// (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
// Pierwiastki w <-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 a,b,x0,fa,fb,f0,t

  a = parseFloat(document
      .frmbincode.inp_a.value)
  b = parseFloat(document
      .frmbincode.inp_b.value)
  if(isNaN(a) || isNaN(b))
    t = "<font color=red><b>" +
        "Złe krańce " +
        "przedziału " + 
        "poszukiwań " +
        "pierwiastka!" +
        "</b></font>"
  else
  {
    t  = "x<sub>0</sub> = "
    fa = f(a); fb = f(b)
    if(fa * fb > 0)
      t = "<font color=red><b>" +
          "Brak pierwiastka" +
          "</b></font>"
    else
    {
      while(Math.abs(a-b)>EPSX)
      {
        x0 = (a + b) / 2
        f0 = f(x0)
        if(Math.abs(f0) < EPS0)
          break
        if(fa * f0 < 0)
          b = x0
        else
        {
          a = x0
          fa = f0
        }
      }
      t += x0
    }
  }
  t = t
  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⟩ oraz ⟨1;2⟩.

Obliczanie
pierwiastka funkcji
metodą Bisekcji


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

   (C)2026 mgr Jerzy Wałaszek I LO w Tarnowie   
Wpisz do pól edycyjnych
krańce przedziału
poszukiwań pierwiastka

a =
b =

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.
W soboty i niedziele reklamy są wyłączane w całym serwisie.
Informacje dodatkowe.