Oprócz systemu dwójkowego w informatyce powszechnie są stosowane dwa systemy - ósemkowy (oktalny) oraz szesnastkowy (heksadecymalny). Powodem ich stosowania jest to, iż bardzo łatwo jest przeliczać pomiędzy nimi a systemem dwójkowym. Liczba ósemkowa jest dla ludzi bardziej czytelna od liczby dwójkowej.
W systemie ósemkowym mamy 8 cyfr: 0, 1, 2, 3, 4, 5, 6 i 7. Wartość liczby ósemkowej obliczamy wg wzoru:
W8 = cn-18n-1 + cn-28n-2 + ... + c282 + c18 + c0
ci, i = 0,1,...,n-1 - kolejne cyfry ósemkowe zapisu liczby
Przykład:
72318 = 7 × 83 + 2 × 82 + 3 × 8 + 1
72318 = 7 × 512 + 2 × 64 + 3 × 8 + 1
72318 = 3584 + 128 + 24 + 1
72318 = 3737
Istnieje również inny algorytm obliczania wartości dowolnej liczby pozycyjnej, zwany schematem Hornera. Postępujemy następująco:
Za wynik W przyjmujemy pierwszą od lewej cyfrę liczby. Kolejne cyfry liczby odczytujemy od strony lewej ku prawej.
Dopóki są dalsze cyfry, wynik W mnożymy przez podstawę systemu i dodajemy do niego kolejną cyfrę, aż do ich wyczerpania.
Na końcu W zawiera wartość liczby.
Przykład:
Mamy znaleźć wartość liczby ósemkowej 72318. Kolejne cyfry to 7, 2, 3 i 1. Zaczynamy:
W ← 7
W ← W × 8 + 2 = 7 × 8 + 2 = 58
W ← W × 8 + 3 = 58 × 8 + 3 = 467
W ← W × 8 + 1 = 467 × 8 + 1 = 3737 - koniec
Schemat Hornera wykorzystują programy obliczające wartość liczb w innych systemach pozycyjnych.
Do wyznaczenia zapisu liczby L w systemie ósemkowym możemy wykorzystać poznany wcześniej algorytm dla systemu dwójkowego, po drobnej modyfikacji:
L dzielimy przez podstawę systemu docelowego. Za kolejną od końca cyfrę przyjmujemy resztę z dzielenia. Za nowe L przyjmujemy wynik dzielenia całkowitoliczbowego. Jeśli L jest różne od zera, operację powtarzamy. Inaczej wyświetlamy otrzymane cyfry w kierunku odwrotnym do ich wyznaczenia.
Przykład:
Mamy znaleźć reprezentację liczby 10000 w systemie ósemkowym.
10000 | : 8 = | 1250, | reszta 0 |
1250 | : 8 = | 156, | reszta 2 |
156 | : 8 = | 19, | reszta 4 |
19 | : 8 = | 2 | reszta 3 |
2 | : 8 = | 0 | reszta 2 |
10000 = 234208
Liczby ósemkowe bardzo prosto przeliczamy na system binarny. Jedna cyfra ósemkowa zawsze przechodzi w trzy cyfry binarne:
cyfra ósemkowa |
cyfry dwójkowe |
0 | 000 |
1 | 001 |
2 | 010 |
3 | 011 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
Gdy zamieniamy liczbę ósemkową na odpowiadającą jej co do wartości liczbę binarną, każdą cyfrę ósemkową zastępujemy trzema cyframi binarnymi zgodnie z tabelką. Na przykład, liczba ósemkowa 234208 ma w systemie dwójkowym następującą postać:
234208 → | 2 | 3 | 4 | 2 | 0 | |
010 | 011 | 100 | 010 | 000 | →0100111000100002 |
Zwróć uwagę, że dla człowieka liczba ósemkowa jest bardziej czytelna od jej odpowiednika dwójkowego. To jest właśnie powód popularności systemu ósemkowego wśród programistów, którzy muszą przekazywać do programów wartości związane z systemem dwójkowym.
W drugą stronę postępujemy podobnie. Liczbę dwójkową dzielimy na trójki bitów. Jeśli ostatnia trójka jest niepełna, uzupełniamy ją bitami o wartości 0. Następnie każdą z trójek zastępujemy odpowiadającą im cyfrą ósemkową. Konwersja skończona. Dla przykładu przekształćmy jakąś liczbę dwójkową na ósemkową:
11011101010111010101012 → | 001 | 101 | 110 | 101 | 011 | 101 | 010 | 101 | |
1 | 5 | 6 | 5 | 3 | 5 | 2 | 5 | → 156535258 |
System szesnastkowy posiada 16 cyfr: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. Pierwsze 10 cyfr jest takie same jak w systemie dziesiętnym. Za kolejne 6 cyfr przyjęto pierwsze litery alfabetu. Litery te w zapisie liczby mogą być małe lub duże. Wartości tych cyfr to kolejno A=10, B=11, C= 12, D=13, E=14, F=15.
Wartość liczby szesnastkowej obliczamy ze wzoru:
W16 = cn-116n-1 + cn-216n-2 + ... + c2162 + c116 + c0
ci, i = 0,1,...,n-1 - kolejne cyfry szesnastkowe zapisu liczby
Przykład:
AFD316 = 10 × 163 + 15 × 162 + 13 × 16 + 3
AFD316 = 10 × 4096 + 15 × 256 + 13 × 16 + 3
AFD316 = 40960 + 3840 + 208 + 3
AFD316 = 45011
To samo schematem Hornera:
W ← 10
W ← W × 16 + 15 = 160 + 15 = 175
W ← W × 16 + 13 = 2800 + 13 = 2813
W ← W × 16 + 3 = 45008 + 3 = 45011
Liczbę dziesiętną przeliczamy na 16 wg poznanego schematu:
Przykład:
Mamy znaleźć reprezentację liczby 99999 w systemie szesnastkowym.
99999 | : 16 = | 6249, | reszta 15 - cyfra F |
6249 | : 16 = | 390, | reszta 9 |
390 | : 16 = | 24, | reszta 6 |
24 | : 16 = | 1. | reszta 8 |
1 | : 16 = | 0, | reszta 1 |
99999 = 1869F16
Liczby szesnastkowe również jest łatwo przeliczać na liczby dwójkowe. W tym przypadku każda cyfra szesnastkowa zastępuje cztery cyfry binarne - dzięki temu liczby szesnastkowe bardzo dobrze odwzorowują dane 8, 16, 32 bitowe. Tabelka konwersji jest następująca:
cyfra szesnastkowa |
cyfry dwójkowe |
0 | 0000 |
1 | 0001 |
2 | 0010 |
3 | 0011 |
4 | 0100 |
5 | 0101 |
6 | 0110 |
7 | 0111 |
8 | 1000 |
9 | 1001 |
A | 1010 |
B | 1011 |
C | 1100 |
D | 1101 |
E | 1110 |
F | 1111 |
Przeliczanie liczby szesnastkowej na ósemkową polega na zamianie każdej cyfry szesnastkowej grupą 4 cyfr binarnych:
AF9D716 → | A | F | 9 | D | 7 | |
1010 | 1111 | 1001 | 1101 | 0111 | →101011111001110101112 |
W drugą stronę bity rozdzielamy poczynając od końca liczby na grupy 4 bitowe. Ostatnia grupa może być niepełna - dopełniamy ją bitami o wartości 0. Każdą grupę zastępujemy odpowiadającą im cyfrą szesnastkową:
11011111011111110001012 → | 0011 | 0111 | 1101 | 1111 | 1100 | 0101 | |
3 | 7 | D | F | C | 5 | → 37DFC516 |
Poniższy program w języku C++ oblicza wartość liczby pozycyjnej w dowolnym systemie od 2 do 16. Cyfry większe od 9 należy podawać jako duże litery. Na początku wpisujemy podstawę systemu, w którym jest zapisana liczba, a następnie samą liczbę.
// Obliczanie wartości liczb pozycyjnych // (C)2011 I LO w Tarnowie //-------------------------------------- #include <iostream> using namespace std; int main() { char cyfry[256]; unsigned p,i,W,c; cin >> p; // odczytujemy podstawę cin >> cyfry; // odczytujemy cyfry W = cyfry[0] - 48; // wartość cyfry if(W > 9) W -= 7; // korekta dla cyfr literowych for(i = 1; cyfry[i]; i++) { c = cyfry[i] - 48; if(c > 9) c -= 7; W = W * p + c; } cout << W; return 0; } |
16 CCFF95 13434773 |
Drugi program przelicza podaną liczbę dziesiętną na liczbę w innym systemie liczbowym. Pierwszy parametr to podstawa systemu docelowego. Drugi parametr to wartość dziesiętna do przeliczenia.
// Przeliczanie na inny system liczbowy // (C)2011 I LO w Tarnowie //-------------------------------------- #include <iostream> using namespace std; int main() { char cyfry[256]; unsigned p,i,L,c; cin >> p; // odczytujemy podstawę cin >> L; // odczytujemy liczbę for(i = 0; L; i++) { c = L % p; // wyliczamy cyfrę if(c > 9) c += 7; // poprawka na cyfry literowe cyfry[i] = c + 48; // wstawiamy cyfrę do tablicy L /= p; // modyfikujemy liczbę } do cout << cyfry[--i]; // cyfry wyświetlamy odwrotnie while(i); cout << endl; return 0; } |
16 65535 FFFF |