Serwis Edukacyjny
w 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

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

Całkowity pierwiastek kwadratowy

SPIS TREŚCI
Podrozdziały

Problem

Znaleźć 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ść:

p2x

Rozwiązanie nr 1

Problem możemy rozwiązać następująco.

Tworzymy ciąg kwadratów kolejnych liczb całkowitych począwszy od 0:

02 12 22 32i2

do momentu, gdy dla pewnego i otrzymamy spełnioną nierówność i2 > x. Wtedy p = i-1.

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-1)-szego.

 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 – od i-tej różnicy pierwszego rzędu odejmujemy poprzedzającą ją, (i-1)-szą różnicę.

 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:

  • ciągu kwadratów i2 → 0
  • ciągu różnic pierwszego rzędu r1i → 1
  • ciągu różnic drugiego rzędu r2i → 2

Mając te trzy wartości możemy rekurencyjnie konstruować ciąg kolejnych kwadratów:

a0 = 0, r1 = 1, r2 = 2, 
gdzie a0 – pierwszy wyraz ciągu kwadratów

Dla i > 0 mamy:

r1i = r1(i-1)+r2 – kolejna różnica pierwszego rzędu powstaje
                 z poprzedniej przez dodanie różnicy drugiego rzędu
ai = ai-1+r1i   – 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.

Algorytm obliczania całkowitego pierwiastka kwadratowego –  wersja nr 1

Wejście:

x : liczba, której pierwiastek obliczamy; x ≥ 0, x ∈ R.

Wyjście:

Całkowity pierwiastek kwadratowy z x.

Elementy pomocnicze:

i : numery wyrazów ciągu kwadratów; i ∈ C.
a : wyraz ciągu kwadratów; a ∈ C.
r1 : różnica pierwszego rzędu; r1 ∈ N.
r2 : różnica drugiego rzędu; r2 ∈ N.

Lista kroków:

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 ax, ; szukamy pierwszego wyrazu a większego od x
     wykonuj K06…K08
K06:   a  ← a+r1  ; następny kwadrat
K07:   r1r1+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

Przykładowe programy

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.
C++
// 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

Obliczanie całkowitego pierwiastka kwadratowego
(C)2020 mgr Jerzy Wałaszek

x =


Na początek:  podrozdziału   strony 

Rozwiązanie nr 2

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.

Algorytm obliczania całkowitego pierwiastka kwadratowego –  wersja nr 2

Wejście:

x : liczba, której pierwiastek obliczamy; x ≥ 0, x ∈ C.

Wyjście:

Całkowity pierwiastek kwadratowy z x.

Elementy pomocnicze:

p1, p2 : kolejne przybliżenia pierwiastka z x; p1, p2 ∈ C.

Lista kroków:

K01: Jeśli x > 1,  ; pierwiastki > 1 liczymy
     to idź do kroku K04
K02: p2x ; inne nie
K03: Idź do kroku K09
K04: p1 ← 0 ; zapewniamy |p1-p2| > 1
K05: p2x shr 1 ; pierwsze przybliżenie pierwiastka
K06: Dopóki |p1-p2| > 1: ; w pętli wyliczamy kolejne przybliżenia
     wykonuj kroki K07…K08
K07:   p1p2 ; 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 p2p2-1 ; zmniejszamy je
K09: Zakończ z wynikiem p2

Przykładowe programy

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.
C++
// 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()

Na początek:  podrozdziału   strony 

Rozwiązanie nr 3

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.

Algorytm obliczania całkowitego pierwiastka kwadratowego –  wersja nr 3

Wejście:

x : liczba, której pierwiastek obliczamy; x ≥ 0, x ∈ C.

Wyjście:

Całkowity pierwiastek kwadratowy z x.

Elementy pomocnicze:

mb : zawiera maskę bitową z ustawionym jednym bitem. Maska jest 64 bitowa.
px : obliczana wartość pierwiastka; px ∈ C.

Lista kroków:

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 mbmb shr 2
K04: Dopóki mb ≠ 0: ; wyznaczamy kolejne bity pierwiastka
     wykonuj kroki K05…K09
K05: tpx+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: xx-t  ; usuwamy bity z x
K08: pxt+mb ; dodajemy bit maski do px
K09: pxpx shr 1 ; przesuwamy bity pierwiastka o 1 w prawo
K09: mbmb shr 2 ; bity maski przesuwamy o 2 w prawo
K10: Zakończ z wynikiem px

Przykładowe programy

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.
C++
// 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()

Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2024 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.