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 |
©2023 mgr Jerzy Wałaszek
|
W poprzednich dwóch rozdziałach nauczyliśmy was obliczać wartość liczby zapisanej w dowolnym systemie pozycyjnym. Teraz zajmiemy się zadaniem odwrotnym - jak przedstawić daną liczbę w systemie pozycyjnym o podstawie p.
Problem sprowadza się do znalezienia kolejnych cyfr zapisu liczby w systemie docelowym. Wartość liczby L jest równa zgodnie ze wzorem:
Do wydobycia poszczególnych cyfr Ci , i = 0,1,2,...,n-1, są nam potrzebne dwa działania:
Oba działania występują powszechnie we wszystkich językach programowania. Wyjątkiem jest JavaScript, który posiada swobodne typy danych, zatem brak w nim dzielenia całkowitoliczbowego, ale można sobie z tym w prosty sposób poradzić.
Realizacja operacji div i mod | ||
---|---|---|
Pascal | div mod |
a div b a mod b |
C++ | div mod |
a / b a % b |
Basic | div mod |
a \ b a MOD b |
JavaScript | div mod |
Math.floor(a / b) a % b |
Jeśli podzielimy L przez p, otrzymamy:
Ostatnia cyfra c0 nie dzieli się przez p (każda cyfra jest mniejsza od podstawy systemu), zatem będzie resztą z dzielenia całkowitoliczbowego L przez p. Pozostała część wyrażenia jest jak widać podzielna przez p. Zauważ, iż w wyniku dostajemy liczbę z mniejszą ilością cyfr. W porównaniu z poprzednią liczbą wszystkie cyfry są przesunięte o 1 pozycję w prawo - teraz najmłodszą cyfrą jest c1. Operację powyższą powtarzamy aż do znalezienia wszystkich cyfr zapisu liczby.
Przykład:
Przedstawić w systemie piątkowym liczbę 139(10).
L = 139 p = 5 c0 = L mod p = 139 mod 5 = 4 L = L div p = 139 div 5 = 27 c1 = L mod p = 27 mod 5 = 2 L = L div p = 27 div 5 = 5 c2 = L mod p = 5 mod 5 = 0 L = L div p = 5 div 5 = 1 c3 = L mod p = 1 mod 5 = 1 L = L div p = 1 div 5 = 0 - kończymy, ponieważ wynik dzielenia daje wartość 0. 139(10) = 1024(5). |
Praktycznie działania te wykonujemy w słupku dzieląc całkowitoliczbowo liczbę przez podstawę systemu i wypisując reszty z dzielenia. Gdy rachunki zakończymy, otrzymane reszty odczytujemy w kierunku z dołu do góry otrzymując kolejne cyfry zapisu liczby.
Przykład:
Przedstawić w systemie czwórkowym liczbę 2743(10).
2743 div 4 = | 685 | i reszta 3 |
685 div 4 = | 171 | i reszta 1 |
171 div 4 = | 42 | i reszta 3 |
42 div 4 = | 10 | i reszta 2 |
10 div 4 = | 2 | i reszta 2 |
2 div 4 = | 0 | i reszta 2 - koniec, ponieważ wynik dzielenia wynosi 0 |
2743(10) = 222313(4) |
Przedstawić w systemie dziewiątkowym liczbę 35921(10).
35921 div 9 = | 3991 | i reszta 2 |
3991 div 9 = | 443 | i reszta 4 |
443 div 9 = | 49 | i reszta 2 |
49 div 9 = | 5 | i reszta 4 |
5 div 9 = | 0 | i reszta 5 - koniec |
35921(10) = 54242(9). |
Przedstawić w systemie trójkowym liczbę 325748(10).
325748 div 3 = | 108582 | i reszta 2 |
108582 div 3 = | 36194 | i reszta 0 |
36194 div 3 = | 12064 | i reszta 2 |
12064 div 3 = | 4021 | i reszta 1 |
4021 div 3 = | 1340 | i reszta 1 |
1340 div 3 = | 446 | i reszta 2 |
446 div 3 = | 148 | i reszta 2 |
148 div 3 = | 49 | i reszta 1 |
49 div 3 = | 16 | i reszta 1 |
16 div 3 = | 5 | i reszta 1 |
5 div 3 = | 1 | i reszta 2 |
1 div 3 = | 0 | i reszta 1 - koniec |
325748(10) = 121112211202(3). |
L - przeliczana liczba, L ∈ N + {0} |
p - podstawa docelowego systemu pozycyjnego, p ∈ N, p ∈ {2,3,...,10} |
Ciąg znaków s reprezentujący zapis liczby L w systemie pozycyjnym o podstawie p.
s | - przechowuje docelowy zapis liczby. |
c | - przechowuje wartość cyfry, c ∈ N + {0} |
kod(znak) | - funkcja zwraca kod ASCII znaku |
znak(kod) | - zwraca znak ASCII o podanym kodzie |
K01: | Czytaj L i p |
K02: | s ← "" |
K03: | c ← L mod p |
K04: | s ← znak(c + kod('0')) + s |
K05: | L ← L div p |
K06: | Jeśli L = 0, to pisz s i zakończ Inaczej idź do kroku K03. |
Odczytujemy liczbę L, którą chcemy przeliczyć oraz podstawę p docelowego systemu pozycyjnego. Podany algorytm pracuje poprawnie tylko dla podstaw p od 2 do 10 (dlaczego?).
Wyliczone cyfry będziemy odkładać w zmiennej łańcuchowej s. Inicjujemy ją pustym tekstem.
Rozpoczynamy pętlę warunkową, która będzie wykonywana, aż liczba L osiągnie wartość 0. Wewnątrz pętli obliczamy wartość ostatniej cyfry liczby L i umieszczamy wynik w zmiennej c. Aby wstawić cyfrę do zmiennej łańcuchowej s musimy ją wyrazić za pomocą kodu ASCII. Dlatego w wyrażeniu wyliczamy kod znaku cyfry jako sumę wartości cyfry oraz kodu cyfry 0. Na przykład dla cyfry 5 otrzymamy kod 5 + 48 = 53 (cyfra 0 ma w ASCII kod 48). Znak o kodzie 53 to właśnie cyfra 5. Obliczony kod cyfry przekształcamy w znak i łączymy z zawartością łańcucha s. Bardzo ważna jest tutaj kolejność łączenia. Cyfra musi być dopisana przed poprzednio wyliczonymi cyframi, ponieważ algorytm wyznacza cyfry od końca zapisu liczby. Po dołączeniu cyfry do łańcucha liczbę L dzielimy całkowitoliczbowo przez p i przechodzimy do sprawdzenia warunku zakończenia pętli. Jeśli po operacji dzielenia liczba L nie jest równa zero, to nie zostały jeszcze wyznaczone wszystkie cyfry, zatem pętla kontynuuje się. Jeśli natomiast liczba L jest równa zero, zmienna s zawiera komplet cyfr liczby w docelowym systemie pozycyjnym. Wychodzimy z pętli, wypisujemy zawartość łańcucha s i kończymy algorytm.
Na podstawie algorytmu tworzymy programy
wyznaczające zapis podanej liczby dziesiętnej w systemie pozycyjnym o podstawie
od 2 do 10. Zwróć uwagę, iż algorytm nie sprawdza poprawności danych
wprowadzonych przez użytkownika. Jeśli użytkownik poda podstawę systemu
docelowego równą 1, to pętla warunkowa nigdy nie zakończy się dla L
C++// Znajdowanie reprezentacji liczby // w systemie pozycyjnym o podstawie // p równej od 2 do 10 //---------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //---------------------------------- #include <iostream> #include <string> using namespace std; main() { string s; unsigned c,L,p; char z[1]; cout << "Przeliczanie podanej liczby na zapis\n" "w systemie pozycyjnym o podstawie p\n" "------------------------------------\n" "(C)2005 mgr J. Walaszek I LO Tarnow\n\n" "Podaj liczbe = "; cin >> L; cout << "\nPodaj p (2..10) = "; cin >> p; cout << "\n" << L << "(10) = "; s = ""; do { c = L % p; s = char(c + 48) + s; L = L / p; } while(L != 0); cout << s << "(" << p << ")\n\nNacisnij ENTER...\n"; cin.getline(z,1); cin.getline(z,1); } |
Pascal// Znajdowanie reprezentacji liczby // w systemie pozycyjnym o podstawie // p równej od 2 do 10 //---------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //---------------------------------- program przelicz; {$APPTYPE CONSOLE} var s : string; c,L,p : cardinal; begin writeln('Przeliczanie podanej liczby na zapis'); writeln('w systemie pozycyjnym o podstawie p'); writeln('------------------------------------'); writeln('(C)2005 mgr J. Walaszek I LO Tarnow'); writeln; write('Podaj liczbe = '); readln(L); writeln; write('Podaj p (2..10) = '); readln(p); writeln; write(L,'(10) = '); s := ''; repeat c := L mod p; s := char(c + ord('0')) + s; L := L div p; until L = 0; writeln(s,'(',p,')'); writeln; writeln('Nacisnij klawisz ENTER...'); readln; end. |
Basic' Znajdowanie reprezentacji liczby ' w systemie pozycyjnym o podstawie ' p równej od 2 do 10 '---------------------------------- ' (C)2005 mgr Jerzy Wałaszek ' I Liceum Ogólnokształcące ' im. K. Brodzińskiego ' w Tarnowie '---------------------------------- Option Explicit On Module Module1 Sub Main() Dim s As String Dim c, L, p As UInteger Console.WriteLine("Przeliczanie podanej liczby na zapis") Console.WriteLine("w systemie pozycyjnym o podstawie p") Console.WriteLine("------------------------------------") Console.WriteLine("(C)2005 mgr J. Walaszek I LO Tarnów") Console.WriteLine() Console.Write("Podaj liczbę = ") : L = Val(Console.ReadLine) Console.WriteLine() Console.Write("Podaj p (2..10) = ") : p = Val(Console.ReadLine) Console.WriteLine() Console.Write("{0}(10) = ", L) s = "" Do c = L Mod p s = Chr(c + Asc("0")) + s L = L \ p Loop Until L = 0 Console.WriteLine("{0}({1})", s, p) Console.WriteLine() Console.WriteLine("KONIEC. Naciśnij dowolny klawisz...") Console.ReadLine() End Sub End Module |
JavaScript<html> <head> </head> <body> <div align="center"> <form style="BORDER-RIGHT: #ff9933 1px outset; PADDING-RIGHT: 4px; BORDER-TOP: #ff9933 1px outset; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: #ff9933 1px outset; PADDING-TOP: 1px; BORDER-BOTTOM: #ff9933 1px outset; BACKGROUND-COLOR: #ffcc66" name="frmprzelicz"> <h3 id="data_out" style="text-align: center"> Wyznaczanie zapisu liczby L<br> w systemie pozycyjnym o podstawie p</h3> <p style="TEXT-ALIGN: center"> (C)2005 mgr Jerzy Wałaszek I LO w Tarnowie </p> <hr> <div align="center"> <table border="0" cellpadding="4" style="border-collapse: collapse"> <tr> <td align="right">Liczba =</td> <td> <input value="23314" name="inp_l" size="20" style="text-align: right"> </td> </tr> <tr> <td align="right">Podstawa (2...10) =</td> <td> <input value="5" name="inp_p" size="20" style="text-align: right"> </td> </tr> </table> </div> <p style="TEXT-ALIGN: center"> <input onclick="main();" type="button" value="Przelicz" name="B1"> </p> <p id="out_t" style="TEXT-ALIGN: center">...</p> </form> <script language=javascript> // Znajdowanie reprezentacji liczby // w systemie pozycyjnym o podstawie // p równej od 2 do 10 //---------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //---------------------------------- function main() { var s,t,p,L,c; p = parseInt(document.frmprzelicz.inp_p.value); L = parseInt(document.frmprzelicz.inp_l.value); s = "<font color=Red><b>Złe dane</b></font>"; if(!isNaN(p) && !isNaN(L)) { s = ""; t = L + "<sub>(10)</sub> = "; do { c = L % p; s = String.fromCharCode(c + 48) + s; L = Math.floor(L / p); } while(L != 0); s = t + s + "<sub>(" + p + ")</sub>"; }; document.getElementById("out_t").innerHTML = s; } </script> </div> </body> </html> |
Wynik: |
Przeliczanie podanej liczby
na zapis w systemie pozycyjnym o podstawie p ------------------------------------ (C)2005 mgr J. Walaszek I LO Tarnów Podaj liczbę = 25 Podaj p (2..10) = 4 25(10) = 121(4) KONIEC. Naciśnij dowolny klawisz... |
Przelicz liczbę dziesiętną o wartości równej 1000 kolejno na system dwójkowy, trójkowy, czwórkowy, piątkowy i ósemkowy.
Wyznaczmy złożoność obliczeniową zaprezentowanego algorytmu przy znajdowaniu
reprezentacji liczby L w systemie pozycyjnym o podstawie p. Za
operację dominującą przyjmijmy 1 pętli warunkowej. Każdy
obieg zmniejsza wartość liczby L p razy. Obiegi wykonywane są do
momentu, aż L osiągnie wartość 0. Zatem ich ilość wyraża się wzorem:
Ze wzoru wynika, iż algorytm jest klasy O(logp n), gdzie n oznacza wartość liczby, której reprezentację wyznaczamy w systemie pozycyjnym o podstawie p.
Zobacz dalej...
Wartość liczby pozycyjnej | Schemat Hornera | Wartość liczby stałoprzecinkowej | Przeliczanie na zapis stałoprzecinkowy | Systemy pozycyjne o podstawie większej od 10 | Zapis zmiennoprzecinkowy
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2023 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.