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 systemach o podstawie p większej od 10 obowiązują wszystkie podane przez nas wzory i algorytmy. Jedyną różnicą są cyfry, których musi być dokładnie tyle ile wynosi podstawa p. Niestety, cyfr "wymyślono" tylko 10. Brakujące cyfry zastępujemy kolejnymi literkami alfabetu, I tak:
litera A (lub a) odpowiada cyfrze o
wartości 10 litera B (lub b) odpowiada cyfrze o wartości 11 litera C (lub c) odpowiada cyfrze o wartości 12 ... |
Sposób ten pozwala nam zapisywać liczby w systemach pozycyjnych o podstawie od 2 do 36. Dla większych podstaw musimy wymyślić inną formę przedstawiania cyfr, ponieważ braknie nam literek. Na szczęście są to problemy czysto teoretyczne, ponieważ w informatyce będziemy się spotykać tylko z systemem dwójkowym, ósemkowym, dziesiętnym oraz szesnastkowym. Inne systemy stosowane są marginalnie.
Przykład:
Oblicz wartość liczby pozycyjnej ABCD,EF(16).
ABCD,EF(16) = A · 163 + B · 162 + C · 161 + D · 160 + E · 16-1 + F · 16-2 |
Zastępujemy znaki cyfr ich wartościami liczbowymi:
ABCD,EF(16)
= 10 · 163 + 11 · 162
+ 12 · 161 + 13 · 160
+ 14 · 16-1 + 15 · 16-2 ABCD,EF(16) = 10 · 4096 + 11 · 256 + 12 · 16 + 13 · 1 + 14 · 1/16 + 15 · 1/256 ABCD,EF(16) = 40960 + 2816 + 192 + 13 + 14/16 + 15/256 ABCD,EF(16) = 43981 + 224/256 + 15/256 ABCD,EF(16) = 43981 + 239/256 = 43981,93359375(10) |
Przelicz liczbę dziesiętną 2427,423 na system piętnastkowy z dokładnością do 6 cyfr po przecinku.
W systemie piętnastkowym mamy piętnaście cyfr {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E}.
Rozdzielamy liczbę na część całkowitą i ułamkową i wyznaczamy wartości kolejnych cyfr, które następnie zastępujemy odpowiadającymi tym wartością znakami cyfr.
2427 div 15 = | 161 | i reszta 12 | - cyfra C |
161 div 15 = | 10 | i reszta 11 | - cyfra B |
10 div 15 = | 0 | i reszta 10 | - cyfra A |
2427(10) = ABC(15) |
0,423 · 15 = | 6,345 | - cyfra 6 |
0,345 · 15 = | 5,175 | - cyfra 5 |
0,175 · 15 = | 2,625 | - cyfra 2 |
0,625 · 15 = | 9,375 | - cyfra 9 |
0,375 · 15 = | 5,625 | - cyfra 5 |
0,625 · 15 = | 9,375 | - cyfra 9 |
0,423(10) = 0,652959...(15) |
Ponieważ w części ułamkowej nie otrzymaliśmy zera, wyznaczona liczba ma
wartość przybliżoną.
Składamy obie wyznaczone części liczby w jedną całość i otrzymujemy wynik:
2427,423(10) = ABC,652959...(15) |
Aby poprawnie przeliczać liczby w systemach o p > 10, podamy dwa proste algorytmy, które kojarzą znak cyfry w postaci ASCII z jej wartością. Algorytmy te wykorzystujemy w programach przy przekształcaniu wartości cyfry na odpowiadający jej znak ASCII oraz przy wyliczaniu wartości cyfry na podstawie jej znaku ASCII.
Obliczanie wartości cyfry ze znaku ASCII |
---|
|
Obliczanie znaku ASCII reprezentującego daną cyfrę |
---|
|
Program przelicza liczby z jednego systemu pozycyjnego (podstawa od 2 do 36) na inny (podstawa od 2 do 36), wykorzystując podane wcześniej algorytmy. W obliczeniach na dalszych pozycjach po przecinku mogą pojawić się błędy spowodowane zaokrąglaniem wartości zmiennoprzecinkowych.
C++// Program przeliczający liczby z jednego // systemu pozycyjnego na inny. //--------------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //--------------------------------------- #include <cmath> #include <iostream> #include <string> using namespace std; // Funkcja zadaje użytkownikowi pytanie, czy chce // zakończyć pracę z programem. Jeśli tak, zwraca // wartość logiczną true. //----------------------------------------------- bool Koniec() { string s; cout << "Koniec pracy z programem ? (T = TAK)"; cin >> s; return ((s != "") && (toupper(s[0]) == 'T')); } // Funkcja sprawdza, czy użytkownik wprowadził // poprawne dane wejściowe. W takim przypadku // zwraca wartość true, inaczej zwraca false. //-------------------------------------------- bool DaneOK(string & s, unsigned p1, unsigned p2) { bool przecinek; unsigned long i,c; if((p1 < 2) || (p1 > 36) || (p2 < 2) || (p2 > 36)) return false; przecinek = false; for(i = 0; i < s.length(); i++) { s[i] = toupper(s[i]); if(s[i] == ',') { if(przecinek) return false; else { przecinek = true; continue; }; }; if((s[i] < '0') || (s[i] > 'Z') || ((s[i] > '9') && (s[i] < 'A'))) return false; c = s[i] - 48; if(c > 9) c -= 7; if(c >= p1) return false; } return true; } // ********************** // *** PROGRAM GŁÓWNY *** // ********************** main() { string s1,s2; unsigned c,i,p1,p2,Lc,Lu,w; bool u; double rLu; char z[1]; cout << "Przelicznik liczb zapisanych w roznych\n" " systemach pozycyjnych\n" "--------------------------------------\n" "(C)2005 mgr Jerzy Walaszek I LO Tarnow\n"; do { cout << "\nPodaj liczbe wejsciowa = "; cin >> s1; cout << "\nPodaj podstawe wejsciowa = "; cin >> p1; cout << "\nPodaj podstawe docelowa = "; cin >> p2; cout << endl; if(DaneOK(s1,p1,p2)) { Lc = Lu = 0; w = 1; u = false; for(i = 0; i < s1.length(); i++) if(s1[i] == ',') u = true; else { c = s1[i] - 48; if(c > 9) c -= 7; if(u) { Lu = p1 * Lu + c; w *= p1; } else Lc = p1 * Lc + c; } rLu = (double)(Lu) / w; s2 = ""; do { c = Lc % p2; if(c < 10) s2 = (char)(c + 48) + s2; else s2 = (char)(c + 55) + s2; Lc /= p2; } while(Lc); if(Lu) { s2 += ','; w = (15 * logl(10) / logl(p2)); // ograniczamy cyfry po przecinku while((w > 0) && (s2.length() < 32)) { w--; rLu *= p2; c = (unsigned)floor(rLu); if(c < 10) s2 += (char)(c + 48); else s2 += (char)(c + 55); rLu = rLu - c; } while(s2[s2.length()-1] == '0') s2.erase(s2.length()-1); } cout << s1 << "(" << p1 << ") = " << s2 << "(" << p2 << ")\n"; } else cout << "Zle dane. Obliczenia przerwane.\n"; cout << endl; } while(!Koniec()); } |
Pascal// Program przeliczający liczby z jednego // systemu pozycyjnego na inny. //--------------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //--------------------------------------- program Systemy; {$APPTYPE CONSOLE} // Funkcja zadaje użytkownikowi pytanie, czy chce // zakończyć pracę z programem. Jeśli tak, zwraca // wartość logiczną true. //----------------------------------------------- function Koniec : boolean; var s : string; begin write('Koniec pracy z programem ? (T = TAK)'); readln(s); Koniec := (s <> '') and (UpCase(s[1]) = 'T'); end; // Funkcja sprawdza, czy użytkownik wprowadził // poprawne dane wejściowe. W takim przypadku // zwraca wartość true, inaczej zwraca false. //-------------------------------------------- function DaneOK(var s : string; p1,p2 : cardinal) : boolean; var przecinek : boolean; i,c : cardinal; begin DaneOK := true; if (p1 < 2) or (p1 > 36) or (p2 < 2) or (p2 > 36) then DaneOK := false; while (s <> '') and (s[1] = ' ') do Delete(s,1,1); przecinek := false; for i := 1 to length(s) do case UpCase(s[i]) of ',' : if przecinek then begin DaneOK := false; break; end else przecinek := true; '0'..'9', 'A'..'Z': begin c := ord(UpCase(s[i])) - 48; if c > 9 then dec(c,7); if c >= p1 then begin DaneOK := false; break; end; end; else begin DaneOK := false; break; end; end; end; // ********************** // *** PROGRAM GŁÓWNY *** // ********************** var s1,s2 : string; c,i,p1,p2,Lc,Lu,w : cardinal; u : boolean; rLu : real; begin writeln('Przelicznik liczb zapisanych w roznych'); writeln(' systemach pozycyjnych'); writeln('--------------------------------------'); writeln('(C)2005 mgr Jerzy Walaszek I LO Tarnow'); repeat writeln; write('Podaj liczbe wejsciowa = '); readln(s1); writeln; write('Podaj podstawe wejsciowa = '); readln(p1); writeln; write('Podaj podstawe docelowa = '); readln(p2); writeln; if DaneOK(s1,p1,p2) then begin Lc := 0; Lu := 0; w := 1; u := false; for i := 1 to length(s1) do if s1[i] = ',' then u := true else begin c := ord(UpCase(s1[i])) - 48; if c > 9 then dec(c,7); if u then begin Lu := p1 * Lu + c; w := p1 * w; end else Lc := p1 * Lc + c; end; rLu := Lu / w; s2 := ''; repeat c := Lc mod p2; if c < 10 then s2 := char(c + 48) + s2 else s2 := char(c + 55) + s2; Lc := Lc div p2; until Lc = 0; if Lu > 0 then begin s2 := s2 + ','; w := Round(15 * ln(10) / ln(p2)); // ograniczamy cyfry po przecinku while (w > 0) and (length(s2) < 32) do begin dec(w); rLu := rLu * p2; c := trunc(rLu); if c < 10 then s2 := s2 + char(c + 48) else s2 := s2 + char(c + 55); rLu := rLu - c; end; while s2[length(s2)] = '0' do Delete(s2,length(s2),1); end; writeln(s1,'(',p1,') = ',s2,'(',p2,')'); end else writeln('Zle dane. Obliczenia przerwane.'); writeln; until Koniec; end. |
Basic' Program przeliczający liczby z jednego ' systemu pozycyjnego na inny. '--------------------------------------- ' (C)2005 mgr Jerzy Wałaszek ' I Liceum Ogólnokształcące ' im. K. Brodzińskiego ' w Tarnowie '--------------------------------------- Option Explicit On Module Module1 ' Funkcja zadaje użytkownikowi pytanie, czy chce ' zakończyć pracę z programem. Jeśli tak, zwraca ' wartość logiczną true. '----------------------------------------------- Function Koniec() As Boolean Dim s As String Console.WriteLine("Koniec pracy z programem ? (T = TAK) ") s = Console.ReadLine.ToUpper() Return (s = "T") End Function ' Funkcja sprawdza, czy użytkownik wprowadził ' poprawne dane wejściowe. W takim przypadku ' zwraca wartość true, inaczej zwraca false. '-------------------------------------------- Function DaneOK(ByVal s As String, ByVal p1 As UInteger, _ ByVal p2 As UInteger) As Boolean Dim przecinek As Boolean Dim i, c As UInteger Dim x As Char If (p1 < 2) Or (p1 > 36) Or (p2 < 2) Or (p2 > 36) Then Return False End If s = s.TrimStart(" ") przecinek = False For i = 0 To s.Length() - 1 x = s.Chars(i) If x = "," Then If przecinek Then Return False Else przecinek = True End If ElseIf ((x >= "0") And (x <= "9")) Or _ ((x >= "A") And (x <= "Z")) Then c = Asc(x) - 48 If c > 9 Then c = c - 7 If c >= p1 Then Return False Else : Return False End If Next Return True End Function Sub Main() Dim s1, s2 As String Dim c, i, p1, p2, Lc, Lu, w As UInteger Dim u As Boolean, rLu As Double Console.WriteLine("Przelicznik liczb zapisanych w różnych") Console.WriteLine(" systemach pozycyjnych") Console.WriteLine("--------------------------------------") Console.WriteLine("(C)2005 mgr Jerzy Wałaszek I LO Tarnów") Do Console.WriteLine() Console.Write("Podaj liczbę wejściową = ") s1 = Console.ReadLine.ToUpper() Console.WriteLine() Console.Write("Podaj podstawę wejściową = ") p1 = Val(Console.ReadLine) Console.WriteLine() Console.Write("Podaj podstawę docelową = ") p2 = Val(Console.ReadLine) Console.WriteLine() If DaneOK(s1, p1, p2) Then Lc = 0 : Lu = 0 : w = 1 : u = False For i = 0 To s1.Length() - 1 If s1.Chars(i) = "," Then u = True Else c = Asc(s1.Chars(i)) - 48 If c > 9 Then c = c - 7 If u Then Lu = p1 * Lu + c : w *= p1 Else Lc = p1 * Lc + c End If End If Next rLu = Lu / w : s2 = "" Do c = Lc Mod p2 If c < 10 Then s2 = Chr(c + 48) + s2 Else s2 = Chr(c + 55) + s2 End If Lc \= p2 Loop Until Lc = 0 If Lu > 0 Then s2 += "," w = Int(15 * Math.Log(10) / Math.Log(p2)) While (w > 0) And (s2.Length() < 32) w -= 1 rLu *= p2 c = Int(rLu) If c < 10 Then s2 += Chr(c + 48) Else s2 += Chr(c + 55) End If rLu -= c End While s2 = s2.TrimEnd("0") End If Console.WriteLine("{0}({1}) = {2}({3})", s1, p1, s2, p2) Else Console.WriteLine("Złe dane. Obliczenia przerwane.") End If Console.WriteLine() Loop Until Koniec() 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"> Przeliczanie liczb zapisanych<br> w różnych systemach pozycyjnych </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 wejściowa =</td> <td> <input value="12,75" name="inp_s1" size="20" style="text-align: right"> </td> <td align="right">Podstawa wejściowa = </td> <td> <input value="10" name="inp_p1" size="20" style="text-align: right"> </td> </tr> <tr> <td align="center" colspan="2"> <input onclick="main();" type="button" value="Wyznacz liczbę docelową" name="B1"> </td> <td align="right">Podstawa docelowa = </td> <td> <input value="2" name="inp_p2" size="20" style="text-align: right"> </td> </tr> </table> </div> <p style="TEXT-ALIGN: center" id="out_t">...</p> </form> <script language=javascript> // Program przeliczający liczby z jednego // systemu pozycyjnego na inny. //--------------------------------------- // (C)2005 mgr Jerzy Wałaszek // I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //--------------------------------------- // Funkcja sprawdza, czy użytkownik wprowadził // poprawne dane wejściowe. W takim przypadku // zwraca wartość true, inaczej zwraca false. //-------------------------------------------- function DaneOK(s,p1,p2) { var przecinek,i,c; if((p1 < 2) || (p1 > 36) || (p2 < 2) || (p2 > 36)) return false; przecinek = false; for(i = 0; i < s.length; i++) { if(s.charAt(i) == ',') { if(przecinek) return false; else { przecinek = true; continue; } } if((s.charAt(i) < '0') || (s.charAt(i) > 'Z') || ((s.charAt(i) > '9') && (s.charAt(i) < 'A'))) return false; c = s.charCodeAt(i) - 48; if(c > 9) c -= 7; if(c >= p1) return false; } return true; } // ********************** // *** PROGRAM GŁÓWNY *** // ********************** function main() { var s1,c,i,p1,p2,Lc,Lu,w,u,rLu,t; s1 = document.frmprzelicz.inp_s1.value; s1 = s1.toUpperCase(); p1 = parseInt(document.frmprzelicz.inp_p1.value); p2 = parseInt(document.frmprzelicz.inp_p2.value); if(isNaN(p1) || isNaN(p2) || !DaneOK(s1,p1,p2)) t = "<font color=Red><b>Złe dane!</b></font>"; else { Lc = Lu = 0; w = 1; u = false; for(i = 0; i < s1.length; i++) if(s1.charAt(i) == ',') u = true; else { c = s1.charCodeAt(i) - 48; if(c > 9) c -= 7; if(u) { Lu = p1 * Lu + c; w *= p1; } else Lc = p1 * Lc + c; } rLu = Lu / w; t = ""; do { c = Lc % p2; if(c < 10) t = String.fromCharCode(c + 48) + t; else t = String.fromCharCode(c + 55) + t; Lc = Math.floor(Lc / p2); } while(Lc); if(Lu) { t += ','; w = (15 * Math.log(10) / Math.log(p2)); // ograniczamy cyfry po przecinku while((w > 0) && (t.length < 32)) { w--; rLu *= p2; c = Math.floor(rLu); if(c < 10) t += String.fromCharCode(c + 48); else t += String.fromCharCode(c + 55); rLu = rLu - c; } while(t.charAt(t.length-1) == '0') t = t.substring(0,t.length-1); } t = s1 + "<sub>(" + p1 + ")</sub> = " + t + "<sub>(" + p2 + ")</sub>"; }; document.getElementById("out_t").innerHTML = t; } </script> </div> </body> </html> |
Wynik: |
Przelicznik liczb zapisanych
w różnych systemach pozycyjnych -------------------------------------- (C)2005 mgr Jerzy Wałaszek I LO Tarnów Podaj liczbę wejściową = 22,1 Podaj podstawę wejściową = 3 Podaj podstawę docelową = 5 22,1(3) = 13,131313131313131313131(5) Koniec pracy z programem ? (T = TAK) |
Oblicz wartości podanych poniżej liczb pozycyjnych:
Przelicz liczbę dziesiętną o wartości 9999(10) kolejno na systemy pozycyjne. Cyfry dodatkowe wpisuj dużymi literkami.
Oblicz wartości podanych poniżej liczb stałoprzecinkowych. Wynik wpisz w postaci części całkowitej i ułamka właściwego, np. 276 2/37. Część całkowitą oddziel od ułamka dokładnie jedną spacją.
Przedstaw liczbę 2893,746(10) w systemie dwudziestkowym z dokładnością do 5 cyfr po przecinku.
W praktyce spotykamy tylko jeden system pozycyjny o podstawie większej od 10 - system szesnastkowy. Jest on powszechnie stosowany do reprezentacji kodów binarnych z uwagi na prostotę konwersji szesnastkowo binarnej. Pozostałe systemy mają znaczenie tylko teoretyczne.
Zobacz dalej...
Wartość liczby pozycyjnej | Schemat Hornera | Przeliczenia na inny zapis pozycyjny | Wartość liczby stałoprzecinkowej | Przeliczanie na zapis stałoprzecinkowy | 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.