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 |
©2025 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 ©2025 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.