Ogólna zasada algorytmu polega na dzieleniu zakresu na połowę i sprawdzaniu, czy element znajdujący się dokładnie pośrodku jest elementem szukanym,
a jeśli nie, to czy jest większy, czy mniejszy od szukanego, oraz na przeszukaniu odpowiednio w prawo i lewo.
W ten sposób szybko zawęża się zakres poszukiwań, aż w końcu otrzymuje się przedział jednoelementowy.
Można wtedy wskazać szukany element lub stwierdzić, że go nie ma.
Jak znaleźć wartość √2 z dokładnością 0,001, jeśli nie ma funkcji pierwiastek?
Stosować możemy jedynie podstawowe operacje arytmetyczne.
Wartość pierwiastka możemy podać z określonym przybliżeniem (nie ma skończonej wartości).
Szukamy zatem liczby a spełniającej nierówność |√2 - a| < przyb
Algorytm można zdefiniować następująco:
Podaj x i przyb | x = 2, przyb = 0.001 |
Ustal końce przedziału a=0 i b=x | a = 0, b = 2 |
Dopóki |b-a| > przyb, wykonuj:
|
Wykonywanie pętli, dopóki |b - a| > 0.001 |
Wynikiem jest c | Ostatni przebieg pętli: 0.0009765625 < 0.001, więc wynikiem jest: 1.4150390625 |
Do zapisu algorytmu potrzebujemy zmiennej rzeczywistej podwójnej długości, czyli long double oraz funkcji obliczającej wartość bezwzględną, czyli
fabs().
Funkcja ta znajduje się w biblitece procedur matematycznych, musimy ją zatem dołączyć: #include <cmath>
Program przedstawia się następująco:
#include <iostream>
#include <cmath>
using namespace std;
double pierwiastek (double x, double przyb) {
double a = 0.0;
double b = x;
double c;
while (fabs(b-a) > przyb) {
c = (a + b)/2;
if(c * c > x)
b = c;
else
a = c;
}
return c;
}
int main() {
double x = 2;
double przyb = 0.001;
cout << "Pierwiastek z " << x << " = " << pierwiastek(x, przyb);
return 0;
}
Metoda opiera się na wzorze:
Tak wygląda nasz algorytm:
pobierz liczbę x<-liczba/2 dopóki |x-liczba/x|> ustalona dokładność wykonuj x=(x+liczba/x)/2 jeżeli x*x równa się liczbie zakończ działanie pętli zwróć x
I bazująca na nim procedura:
double pierwiastek(double liczba)
{
double x = liczba/2;
while(fabs(x-liczba/x)>0.000001)
{
x = (x + liczba/x)/2; //nową wartością boku jest średnia arytmetyczna dwóch poprzednich
cout << x << "\n";
if(x*x == liczba) break;
}
return x;
}