|
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
|
ProblemNależy obliczyć wartość |
Normalnie

Mnożenie dużych liczb jest bardzo kosztowne czasowo. Istnieje zatem naturalne
pytanie, czy takiej operacji potęgowania nie można wykonać przy mniejszej
liczbie mnożeń. Okazuje się, że tak – postąpimy podobnie jak przy mnożeniu – przedstawimy potęgę w postaci sumy potęg

Niech:

gdzie bi

Jeśli dokładnie się przyjrzysz ostatniemu wzorowi, to powinieneś spostrzec, że zbudowany on jest z iloczynu wyrażeń:

Kolejne wartości potęg w prosty sposób obliczamy dynamicznie:

Bity bi wydzielamy z b za pomocą koniunkcji oraz przesuwu w prawo w identyczny sposób jak przy mnożeniu.
Możemy już przystąpić do konstrukcji algorytmu potęgującego.
K01: w ← "1" ; ustawiamy wynik na 1 K02: Jeśli (b and 1) = 1, ; jeśli bit bi = 1, to wymnóż w przez ai to w ← mnóż(w, a) K03: b ← b shr 1 ; przesuń bity w b o jedną pozycję w prawo K04: Jeśli b = 0, ; reszta bitów jest zerowa, kończymy to zakończ K05: a ← mnóż(a, a) ; oblicz kolejne ai K06: Idź do kroku K02 ; kontynuuj pętlę
|
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. |
| Program odczytuje dwie liczby
nieujemne
Uwaga: potęgi dużych liczb mogą wymagać bardzo długiego czasu obliczeń, a wynik nie będzie się mieścił w oknie konsoli. |
Pascal// Potęgowanie dużej liczby przez małą
// Data: 24.10.2012
// (C)2020 mgr Jerzy Wałaszek
//------------------------------------
program bigpower;
// Oblicza sumę podanych liczb
//----------------------------
function dodaj (var x, y : ansistring)
: ansistring;
var
z : ansistring;
p, w, i, j, k, n : integer;
begin
i := length(x);
j := length(y);
n := i; if j < i then n := j;
p := 0;
z := '';
for k := 1 to n do
begin
w := ord(x[i])+ord(y[j])+p-96;
dec(i); dec(j);
p := w div 10;
z := chr((w mod 10)+48)+z;
end;
while i > 0 do
begin
w := ord(x[i])+p-48;
dec (i);
p := w div 10;
z := chr((w mod 10)+48)+z;
end;
while j > 0 do
begin
w := ord(y[j])+p-48;
dec(j);
p := w div 10;
z := chr((w mod 10)+48)+z;
end;
if p > 0 then
z := chr(p+48)+z;
if z = '' then
z := '0';
dodaj := z; // zwracamy wynik dodawania
end;
// Mnoży dużą liczbę a przez małą b
//---------------------------------
function mnoz_ab(a : ansistring;
b : dword)
: ansistring;
var
w : ansistring;
begin
w := '0'; // zerujemy łańcuch wyjściowy
while true do // wykonujemy mnożenie
begin
if(b and 1) = 1 then
w := dodaj(w, a);
b := b shr 1;
if b = 0 then break;
a := dodaj(a, a);
end;
mnoz_ab := w; // zwracamy wynik mnożenia
end;
// Mnoży dwie duże liczby
//-----------------------
function mnoz(var a, b : ansistring)
: ansistring;
var
c, w, z : ansistring;
i : dword;
begin
// mnożymy
w := '0';
z := '';
for i := length(b) downto 1 do
begin
c := mnoz_ab(a, ord(b[i])-48)+z;
w := dodaj(w, c);
z := z+'0';
end;
mnoz := w; // zwracamy wynik mnożenia
end;
//********************
//** PROGRAM GŁÓWNY **
//********************
var
a, w : ansistring;
b : dword;
begin
// odczytujemy dane
readln(a); // duża liczba
readln(b); // mała liczba
// potęgujemy
w := '1';
while true do
begin
if(b and 1) = 1 then
w := mnoz(w, a);
b := b shr 1;
if b <> 0 then
a := mnoz(a, a)
else
break;
end;
// wypisujemy wynik
writeln(w);
end. |
// Potęgowanie dużej liczby przez małą
// Data: 24.10.2012
// (C)2020 mgr Jerzy Wałaszek
//------------------------------------
#include <iostream>
#include <string>
using namespace std;
// Oblicza sumę podanych liczb
//----------------------------
string dodaj(string & x, string & y)
{
string z;
int p, w, i, j, k, n;
i = x.length();
j = y.length();
n = i; if(j < i) n = j;
p = 0;
z = "";
for(k = 1; k <= n; k++)
{
w = (int)(x[--i])+(int)(y[--j])+p-96;
p = w/10;
z = (char)((w%10)+48)+z;
}
while(i)
{
w = x[--i]+p-48;
p = w/10;
z = (char)((w%10)+48)+z;
}
while(j)
{
w = y[--j]+p-48;
p = w/10;
z = (char)((w%10)+48)+z;
}
if(p) z = (char)(p+48)+z;
if(z == "") z = "0";
return z; // zwracamy wynik dodawania
}
// Mnoży dużą liczbę a przez małą b
//---------------------------------
string mnoz_ab(string a,
unsigned int b)
{
string w;
w = "0"; // zerujemy łańcuch wyjściowy
while(true) // wykonujemy mnożenie
{
if(b&1) w = dodaj(w, a);
if(b >>= 1) a = dodaj(a, a);
else break;
}
return w; // zwracamy wynik mnożenia
}
// Mnoży dwie duże liczby
//-----------------------
string mnoz(string & a, string & b)
{
string c, w, z;
int i;
// mnożymy
w = "0";
z = "";
for(i = b.length()-1; i >= 0; i--)
{
c = mnoz_ab(a, b[i]-48)+z;
w = dodaj(w, c);
z = z+"0";
}
return w; // zwracamy wynik mnożenia
}
//********************
//** PROGRAM GŁÓWNY **
//********************
int main()
{
string a, w;
unsigned int b;
// odczytujemy dane
cin >> a; // duża liczba
cin >> b; // mała liczba
// potęgujemy
w = "1";
while(true)
{
if(b & 1) w = mnoz(w, a);
if(b >>= 1) a = mnoz(a, a);
else break;
}
// wypisujemy wynik
cout << w << endl;
} |
Basic' Potęgowanie dużej liczby przez małą
' Data: 24.10.2012
' (C)2020 mgr Jerzy Wałaszek
'------------------------------------
' Oblicza sumę podanych liczb
'----------------------------
Function dodaj(ByRef x As String, _
ByRef y As String) _
As String
Dim As string z
Dim As Integer p, w, i, j, k, n
i = Len(x)
j = Len(y)
n = i: If j < i Then n = j
p = 0
z = ""
For k = 1 To n
w = Asc(Mid(x, i, 1))+_
Asc(Mid(y, j, 1))+p-96
i -= 1: j -= 1
p = w\10
z = Chr((w Mod 10)+48)+z
Next
While i > 0
w = Asc(Mid(x, i, 1))+p-48
i -= 1
p = w\10
z = Chr((w Mod 10)+48)+z
Wend
While j > 0
w = Asc(Mid(y, j, 1))+p-48
j -= 1
p = w\10
z = Chr((w Mod 10)+48)+z
Wend
If p > 0 Then z = Chr(p+48)+z
If z = "" Then z = "0"
dodaj = z
End Function
' Mnoży dużą liczbę a przez małą b
'---------------------------------
Function mnoz_ab(ByRef x As String, _
ByVal b As UInteger) _
As String
Dim As String a, w
a = x
w = "0" ' zerujemy łańcuch wyjściowy
While 1 ' wykonujemy mnożenie
if(b And 1) = 1 Then w = dodaj(w, a)
b Shr= 1
If b = 0 Then Exit While
a = dodaj(a, a)
Wend
mnoz_ab = w ' zwracamy wynik mnożenia
End Function
' Mnoży dwie duże liczby
'-----------------------
Function mnoz(ByRef a As String, _
ByRef b As String) _
As String
Dim As String c, w, z
Dim As UInteger i
' mnożymy
w = "0"
z = ""
For i = Len(b) To 1 Step -1
c = mnoz_ab(a, Asc(Mid(b, i, 1))-48)+z
w = dodaj(w, c)
z += "0"
Next
mnoz = w
End Function
'********************
'** PROGRAM GŁÓWNY **
'********************
Dim As String a, w
Dim As UInteger b
' odczytujemy dane
Open Cons For Input As #1
Line Input a ' duża liczba
Input #1, b ' mała liczba
Close #1
' potęgujemy
w = "1"
while 1
if(b And 1) = 1 Then w = mnoz(w, a)
b Shr= 1
If b = 0 Then Exit While
a = mnoz(a, a)
Wend
' wypisujemy wynik
Print w
End |
Python
(dodatek)# Potęgowanie liczb całkowitych
# Data: 3.04.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------------------
# odczytujemy dane
a = int(input()) # liczba
b = int(input()) # potęga
# potęgujemy
w = 1
while True:
if b & 1: w *= a
b >>= 1
if b > 0: a *= a
else: break
# wypisujemy wynik
print(w)
print()
|
| Wynik: |
123456 123 18030210630404480750814092786593857280734268863855968048844015985795850236081373 25021978269698632257308716304364197947589320743503803676976498146265429266026647 07275874269201777743912313197516323690221274713845895457748735309484337191373255 52792827178520638296799898433048210535094222997067705494083821093695230393940165 67561276077785996672437028140727462194319422930054164116350760212960454933051336 45615566590735965652587934290425473827719935012870093575987789431818047013404691 79577317040576461464605494929884618467829681362559533331161138525173524450544844 3050050547161779229749134489643622579100908331839817426366854332416 |
![]() |
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.