|
Serwis Edukacyjny w I-LO w Tarnowie
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
|
ProblemZnaleźć kwadratowy pierwiastek całkowity nieujemnej liczby rzeczywistej x. Całkowity pierwiastek kwadratowy (ang. integer square root) jest największą liczbą całkowitą p, która spełnia nierówność: p2 ≤ x |
Problem możemy rozwiązać następująco.
Tworzymy ciąg kwadratów kolejnych liczb całkowitych począwszy
02 12 22 32 … i2
do momentu, gdy dla pewnego i otrzymamy spełnioną
nierówność
Pozostaje do rozwiązania efektywny sposób tworzenia kwadratów kolejnych liczb całkowitych. Wypiszmy kilkanaście początkowych wyrazów tego ciągu:
i
|
i2 |
0 |
0 |
1 |
1 |
2 |
4 |
3 |
9 |
4 |
16 |
5 |
25 |
6 |
36 |
7 |
49 |
8 |
64 |
9 |
81 |
10 |
100 |
11 |
121 |
12 |
144 |
… |
… |
Teraz policzmy ciąg różnic pierwszego rzędu:
r1i = i2-(i-1)2, dla i > 0.
Różnica pierwszego rzędu powstaje przez odjęcie od wyrazu
i-tego jego
poprzednika w ciągu, czyli wyrazu
i
|
i2
|
r1 |
0 |
0 |
– |
1 |
1 |
1 |
2 |
4 |
3 |
3 |
9 |
5 |
4 |
16 |
7 |
5 |
25 |
9 |
6 |
36 |
11 |
7 |
49 |
13 |
8 |
64 |
15 |
9 |
81 |
17 |
10 |
100 |
19 |
11 |
121 |
21 |
12 |
144 |
23 |
… |
… |
… |
Ciekawa rzecz – różnice pierwszego rzędu dla naszego ciągu tworzą ciąg kolejnych liczb nieparzystych. Teraz analogicznie utwórzmy ciąg różnic drugiego rzędu:
r2i = r1i-r1i(i-1), dla i > 1
Różnice drugiego rzędu powstają w analogiczny sposób z różnic pierwszego
rzędu, jak różnice pierwszego rzędu powstają z wyrazów ciągu
i
|
i2
|
r1 |
r2
|
0 |
0 |
– |
– |
1 |
1 |
1 |
– |
2 |
4 |
3 |
2 |
3 |
9 |
5 |
2 |
4 |
16 |
7 |
2 |
5 |
25 |
9 |
2 |
6 |
36 |
11 |
2 |
7 |
49 |
13 |
2 |
8 |
64 |
15 |
2 |
9 |
81 |
17 |
2 |
10 |
100 |
19 |
2 |
11 |
121 |
21 |
2 |
12 |
144 |
23 |
2 |
… |
… |
… |
… |
Różnice rzędu drugiego tworzą już ciąg stały o wyrazach równych 2. Nie ma sensu liczyć różnic wyższych rzędów, ponieważ otrzymamy tylko wyrazy równe 0. W tabelce na czerwono zaznaczyliśmy pierwsze wyrazy odpowiednio:
Mając te trzy wartości możemy rekurencyjnie konstruować ciąg kolejnych kwadratów:
a 0 = 0,r 1 = 1,r 2 = 2, gdziea 0 – pierwszy wyraz ciągu kwadratów
Dla
r 1i =r 1(i-1)+r 2 – kolejna różnica pierwszego rzędu powstaje z poprzedniej przez dodanie różnicy drugiego rzędu
a i =a i-1+r 1i – kolejny kwadrat powstaje z poprzedniego przez dodanie wyliczonej różnicy pierwszego rzędu
Zwróć uwagę, iż wykorzystujemy tylko dodawanie, dzięki czemu nasz algorytm jest szybki (dla małych liczb). Jednakże podany algorytm nie jest stosowany w praktyce do wyznaczania wartości pierwiastka kwadratowego. Podajemy go tutaj tylko ze względów dydaktycznych.
K01: a ← 0 ; pierwszy kwadrat 02 K02: r1 ← 1 ; początkowa wartość różnicy pierwszego rzędu K03: r2 ← 2 ; wartość różnic drugiego rzędu K04: i ← 0 ; numer pierwszego wyrazu K05: Dopóki a ≤ x, ; szukamy pierwszego wyrazu a większego od x wykonuj K06…K08 K06: a ← a+r1 ; następny kwadrat K07: r1 ← r1+r2 ; wyliczamy nową różnicę pierwszego rzędu K08: i ← i+1 ; następny numer K09: Zakończ z wynikiem i-1 ; obliczony pierwiastek całkowity
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| W pierwszym wierszu program odczytuje liczbę x. Następnie wyznacza jej całkowity pierwiastek kwadratowy i wypisuje go w wierszu drugim. Dodatkowo w wierszu trzecim program wypisuje kwadrat znalezionego pierwiastka kwadratowego dla celów porównawczych. |
Pascal// Całkowity pierwiastek
// Data: 10.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------
program prg;
var
x : double;
i, a, r1, r2 : longword;
begin
readln(x);
a := 0;
r1 := 1;
r2 := 2;
i := 0;
while a <= x do
begin
inc(a, r1);
inc(r1, r2);
inc(i);
end;
dec(i);
writeln(i);
writeln(i*i);
writeln;
end. |
// Całkowity pierwiastek
// Data: 10.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
using namespace std;
int main()
{
double x;
unsigned int i, a, r1, r2;
cin >> x;
a = 0;
r1 = 1;
r2 = 2;
for(i = 0; a <= x; i++)
{
a += r1;
r1 += r2;
}
i--;
cout << i << endl
<< i * i << endl
<< endl;
return 0;
} |
Basic' Całkowity pierwiastek ' Data: 10.05.2008 ' (C)2020 mgr Jerzy Wałaszek '--------------------------- Dim As Double x Dim As Uinteger i, a, r1, r2 Input x a = 0 r1 = 1 r2 = 2 i = 0 While a <= x a += r1 r1 += r2 i += 1 Wend i -= 1 Print i Print i*i Print End |
Python
(dodatek)# Całkowity pierwiastek
# Data: 19.02.2024
# (C)2024 mgr Jerzy Wałaszek
# --------------------------
x = float(input())
a, r1, r2, i = 0, 1, 2, 0
while a <= x:
a += r1
r1 += r2
i += 1
i -= 1
print(i)
print(i*i)
print()
|
| Wynik: |
135 11 121 |
Druga metoda znajdowania całkowitego pierwiastka kwadratowego pochodzi od Izaaka Newtona (chociaż podobną metodę stosowali już starożytni Babilończycy). Jeśli mamy pewne przybliżenie p pierwiastka liczby x, to lepsze przybliżenie otrzymamy stosując wzór:
p = (p+x/p)/2
Dlaczego to działa? Rozważmy dwa przypadki:
p < √x
Wtedy iloraz x/p jest większy od √x i po dodaniu go do p i podzieleniu sumy przez 2 otrzymamy liczbę większą od poprzedniego p, która przybliża się od dołu do rzeczywistego pierwiastka.
p > √x
Wtedy iloraz x/p jest mniejszy od √x i po dodaniu go do p i podzieleniu sumy przez 2 otrzymamy liczbę mniejszą od poprzedniego p, która przybliża się od góry do rzeczywistego pierwiastka.
Wynika z tego, iż w każdej iteracji otrzymujemy liczbę coraz bliższą wartości pierwiastka. Iterujemy dotąd, aż różnica pomiędzy dwoma kolejnymi przybliżeniami będzie mniejsza lub równa założonej dokładności ε – w przypadku pierwiastków całkowitych jest to 1.
K01: Jeśli x > 1, ; pierwiastki > 1 liczymy to idź do kroku K04 K02: p2 ← x ; inne nie K03: Idź do kroku K09 K04: p1 ← 0 ; zapewniamy |p1-p2| > 1 K05: p2 ← x shr 1 ; pierwsze przybliżenie pierwiastka K06: Dopóki |p1-p2| > 1: ; w pętli wyliczamy kolejne przybliżenia wykonuj kroki K07…K08 K07: p1 ← p2 ; zapamiętujemy bieżące przybliżenie K08: p2 ← (p2+x div p1) shr 1 ; wyliczamy nowe przybliżenie K09: Dopóki p2×p2 > x: ; jeśli przybliżenie było od góry, wykonuj p2 ← p2-1 ; zmniejszamy je K09: Zakończ z wynikiem p2
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| W pierwszym wierszu program odczytuje liczbę x. Następnie wyznacza jej całkowity pierwiastek kwadratowy i wypisuje go w wierszu drugim. Dodatkowo w wierszu trzecim program wypisuje kwadrat znalezionego pierwiastka kwadratowego dla celów porównawczych. |
Pascal// Całkowity pierwiastek kwadratowy
// Data: 11.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------------
program prg;
var
x, p1, p2 : longint;
begin
readln(x);
if x <= 1 then p2 := x
else
begin
p1 := 0;
p2 := x shr 1;
while abs(p1-p2) > 1 do
begin
p1 := p2;
p2 := (p2+x div p2) shr 1;
end;
while p2*p2 > x do dec(p2);
end;
writeln(p2);
writeln(p2*p2);
writeln;
end. |
// Całkowity pierwiastek kwadratowy
// Data: 11.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------------
#include <iostream>
using namespace std;
int main()
{
int x, p1, p2;
cin >> x;
if(x <= 1) p2 = x;
else
{
p1 = 0; p2 = x >> 1;
while(abs(p1-p2) > 1)
{
p1 = p2;
p2 = (p2+x/p2) >> 1;
}
while(p2*p2 > x) --p2;
}
cout << p2 << endl
<< (p2*p2) << endl
<< endl;
return 0;
} |
Basic' Całkowity pierwiastek kwadratowy
' Data: 11.05.2008
' (C)2020 mgr Jerzy Wałaszek
'---------------------------------
Dim As Integer x, p1, p2
Input x
If x <= 1 Then
p2 = x
Else
p1 = 0: p2 = x Shr 1
While Abs (p1-p2) > 1
p1 = p2
p2 = (p2+x\p2) Shr 1
Wend
While p2*p2 > x: p2 -= 1: Wend
End If
Print p2
Print p2*p2
Print
End |
Python
(dodatek)# Całkowity pierwiastek kwadratowy
# Data: 19.02.2024
# (C)2024 mgr Jerzy Wałaszek
# --------------------------
x = int(input())
if x <= 1:
p2 = x
else:
p1 = 0
p2 = x >> 1
while abs(p1-p2) > 1:
p1 = p2
p2 = (p2+x//p2) >> 1
while p2*p2 > x: p2 -= 1
print(p2)
print(p2*p2)
print()
|
Istnieje bardzo szybki algorytm wyznaczania wartości całkowitego pierwiastka kwadratowego, który wykorzystuje binarną reprezentację liczb – czyli idealnie nadaje się do zastosowania dla danych komputerowych, które przecież są liczbami binarnymi. Algorytm wywodzi się z chińskiego abakusa i nie wymaga skomplikowanych działań arytmetycznych – jedynie dodawania oraz przesuwania bitów. Dzięki tym zaletom może być z powodzeniem stosowany w prostych systemach mikrokontrolerów jednoukładowych.
K01: px ← 0 ; początkowa wartość pierwiastka K02: mb ← 1 shl 62 ; maska z ustawionym drugim najstarszym bitem K03: Dopóki mb > x: ; szukamy najstarszej potęgi 4, mniejszej od x wykonuj mb ← mb shr 2 K04: Dopóki mb ≠ 0: ; wyznaczamy kolejne bity pierwiastka wykonuj kroki K05…K09 K05: t ← px+mb ; łączymy bit maski z przybliżeniem pierwiastka K06: Jeśli x < t, ; sprawdzamy, czy dany bit ma być ustawiony. idź do kroku K09 K07: x ← x-t ; usuwamy bity z x K08: px ← t+mb ; dodajemy bit maski do px K09: px ← px shr 1 ; przesuwamy bity pierwiastka o 1 w prawo K09: mb ← mb shr 2 ; bity maski przesuwamy o 2 w prawo K10: Zakończ z wynikiem px
|
Uwaga:
Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| W pierwszym wierszu program odczytuje liczbę x. Następnie wyznacza jej całkowity pierwiastek kwadratowy i wypisuje go w wierszu drugim. Dodatkowo w wierszu trzecim program wypisuje kwadrat znalezionego pierwiastka kwadratowego dla celów porównawczych. |
Pascal// Całkowity pierwiastek kwadratowy
// Data: 11.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------------
program prg;
var
x, px, mb, t : qword;
begin
readln(x);
px := 0; mb := 1 shl 62;
while mb > x do
mb := mb shr 2;
while mb <> 0 do
begin
t := px+mb;
if x >= t then
begin
dec(x, t); px := t+mb;
end;
px := px shr 1;
mb := mb shr 2;
end;
writeln(px);
writeln(px*px);
writeln;
end. |
// Całkowity pierwiastek kwadratowy
// Data: 11.05.2008
// (C)2020 mgr Jerzy Wałaszek
//---------------------------------
#include <iostream>
using namespace std;
int main()
{
unsigned long long x, px, mb, t;
cin >> x;
px = 0; mb = 1; mb <<= 62;
while(mb > x) mb >>= 2;
while(mb)
{
t = px+mb;
if(x >= t)
{
x -= t; px = t+mb;
}
px >>= 1; mb >>= 2;
}
cout << px << endl
<< (px*px)
<< endl << endl;
return 0;
} |
Basic' Całkowity pierwiastek kwadratowy
' Data: 11.05.2008
' (C)2020 mgr Jerzy Wałaszek
'---------------------------------
Dim As Ulongint x, px, mb, t
Input x
px = 0: mb = 1 Shl 62
While mb > x: mb = mb Shr 2: Wend
While mb
t = px+mb
If x >= t Then
x -= t: px = t+mb
End If
px = px Shr 1
mb = mb Shr 2
Wend
Print px
Print px*px
Print
End |
Python
(dodatek)# Całkowity pierwiastek kwadratowy
# Data: 19.02.2024
# (C)2024 mgr Jerzy Wałaszek
# --------------------------
x = int(input())
px = 0
mb = 1 << 62
while mb > x: mb >>= 2
while mb:
t = px+mb
if x >= t:
x -= t
px = t+mb
px >>= 1
mb >>= 2
print(px)
print(px*px)
print()
|
![]() |
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:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.