Temat z kawą na dziś, to przeliczanie jednego systemu liczbowego na inny.
Będzie sporo liczenia, wiec przygotujcie kartkę i coś do pisania.
Trochę teorii…
Ogólnie z przechodzeniem z jednego systemu pozycyjnego na drugi, mamy dwa przypadki w których radzimy sobie tak:
- Mamy przeliczyć system o mniejszej bazie na system o większej bazie (większa ilości znaków), wtedy bierzemy kolejne pozycje liczby którą chcemy przeliczyć, rozpisujemy je za pomocą zapisu potęgowego, zgodnie ze znakami w systemie na który przeliczamy, a następnie sumujemy wynik.
- Mamy przeliczyć system o większej bazie, na systemu do mniejszej bazie, wtedy dzielimy przez bazę systemu mniejszego, liczbę z systemu większego, następnie zapisujemy reszty od końca.
Brzmi skomplikowanie, ale w końcu chodzi o zwykłe dodawanie, mnożenie, potęgowanie i dzielenie, więc wystarczy trochę praktyki po to by się z tym oswoić.
Natomiast pozostaje jeszcze pytanie o sensowność i częstość takich przeliczeń.
Z całą pewnością, w programowaniu nie da się uciec, od systemu dwójkowego, oraz szesnastkowego, np. kolory w CSS często zapisuje się w systemie szesnastkowym(szczególnie przy zapisie RGB), ponieważ łatwo jest wtedy, operować kolorami i przekształcać je.
Podczas pisania sterowników, używa się zapisu binarnego. No i prędzej czy później, spotykasz się, z konsekwencją niemożliwości precyzyjnego zapisu jakiejś liczby, np 0.1.
Jeszcze tylko ostatnia uwaga, przed ćwiczeniami właściwymi , będę używał 4 najpopularniejszych w informatyce systemów liczbowych,
Nazwa | Znaki występujące | Nazwa naukowa | skrót |
dwójkowy | 0,1 | Binarny | bin |
ósemkowy | 0,1,2,3,4,5,6,7 | Oktalny | oct |
dziesiętny | 0,1,2,3,4,5,6,7,8,9 | Decymalny | dec |
szesnastkowy | 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f | Hexalny | hex |
Czas na praktykę.
Problem pierwszy, przechodzenie z systemu niższego na wyższy:
Gdy chcemy przejść z systemu binarnego na decymalny (z dwójkowego na dziesiętny), zgodnie z tym co napisałem wcześniej, rozpisujemy liczbę dwójkową na zapis potęgowy, a potem sumujemy.
Abstrakcyjnie zapis wygląda tak:
(a * 2n-1)+… + (a * 22) + (a * 21) + (a * 20)
Chcemy policzyć 101bin, czyli 101 zapisane dwójkowo/binarnie, na system dziesiętny/decymalny.·
- 101bin rozpisujemy jako sumę kolejnych potęg, zgodnie z pozycją która zajmują, czyli:
1 *22 + 0 * 21 + 1* 20· - Sumujemy:
4dec + 0 dec + 1 dec = 5 dec
Chcemy policzyć 10110 ‑na system szesnastkowy (101 zapisane dziesiętnie, czyli po prostu sto jeden (-: )·
- 10110 rozpisujemy jako sumę kolejnych potęg
1 * 102 + 0 * 101 + 1 * 100 · - A teraz sumujemy 64hex + 1hex = 65hex
Panie jakie 64 przecież 102 to 100! kto panu to tak….
No własnie 64hex to 100dec bo do zapisu używamy nowego systemu, a nowy system ma 16 znaków., Wiec zapis 10hex oznacza 16dec.
zrobimy krok pośredni
10110 <=> 1 * 102 + 0 * 101 + 1 * 100 <=> 100dec + 1dec
zyskaliśmy zamiast jednego trudniejszego zadania 2 mniej trudne. Taki manewr nazywa się stratęgią, dziel i rządź, zapamiętaj tą nazwę bo spotkasz się z nią sporo razy.
Zamiast dużego problemu czyli przeliczenia 101 na zapis hexalny, mamy 2 prostsze czyli przeliczenie 100 i 1 na hexalny. Z jedynką sprawa jest prosta bo 1dec to 1hex
A co ze 100, otóż dzielimy z resztą przez 16, daje nam to 6 i 4 reszty inaczej zapisane to 6* 161 + 4 * 160 <=> 64hex
Wygląda znajomo? No to dochodzimy do dodawania 64hex + 1hex = 65hex
Trenujemy dalej? Przeliczmy 10002 na system dziesiętny pominę rozpisywanie zer
1*23 = 8
I jak, chętni na więcej?
Uwaga będzie sztuczka, która pokaże nam dlaczego system ósemkowy i szesnastkowy, są bardzo wygodne użyciu w stosunku do komputerów.
Przeliczymy 111 111bin na system ósemkowy?
Uprzedzam, spacja nie znalazły się przypadkiem.
Osiem to inaczej 23 ułatwia nam to robotę, ponieważ każda wielokrotność ósemki w zapisie oktalnym to nowy znak, wiec jeśli pogrupujemy to po trzy znaki zapis binarny, każda taka grupa da nam jeden znaj w systemie oktalnym.
Pamiętasz dziel i rządź, zamiast jednego dużego problemu, dwa mniejsze, które tym razem są identyczne 🙂
111bin = 1 * 22 + 1 * 21 + 1 * 20 = 4 + 2 + 1 = 7oct
Czyli wynikiem będzie 77.
Rozpisze całość żebyś mógł zobaczyć skąd się to wzieło. Będzie potrzebna umiejętność wyciągnięcia liczby przed nawias, i zmiana podstawy potęgowania.
111 111bin
Rozpisujemy na:
1 * 25 + 1 * 24 + 1 * 23 + 1 * 22 + 1 * 21 +1 * 20
Wyciągamy każde wielokrotność ósemki przed nawias, czyli inaczej 23
23 * ( 1 * 22 + 1 * 21 +1 * 20 ) + 20*3 * ( 1 * 22 + 1 * 21 +1 * 20 )
Zmieniamy podstawę potęgowania z 2 na 8 i mamy:
81 * (4 + 2 + 1) + 80 * (4 + 2 + 1) <=> 7* 81 + 7* 80
Czyli finalnie 77oct
Jeżeli mielibyśmy zrobić to samo z liczbą 11 111bin, to wtedy metoda jest identyczna, tylko zapisujemy tą liczbę jako 011 111bin.Bo w końcu
0 * 25 + 1 * 24 + 1 * 23 + 1 * 22 + 1 * 21 +1 * 20 to to samo co 1 * 24 + 1 * 23 + 1 * 22 + 1 * 21 +1 * 20
Analogicznie można przechodzić z sytemu dwójkowego na szesnastkowy oraz z ósemkowego na szesnastkowy np:
1111bin = Ehex = 15dec
Cała tabelka
Bin | Oct | Dec | hex |
0000 | 0 | 0 | 0 |
0001 | 1 | 1 | 1 |
0010 | 2 | 2 | 2 |
0011 | 3 | 3 | 3 |
0100 | 4 | 4 | 4 |
0101 | 5 | 5 | 5 |
0110 | 6 | 6 | 6 |
0111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | A |
1011 | 13 | 11 | B |
1100 | 14 | 12 | C |
1101 | 15 | 13 | D |
1110 | 20 | 14 | E |
1111 | 21 | 15 | F |
W drugą stronę czyli np. z sytemu ósemkowego na dwójkowy przechodzi się równie łatwo.
Np 731oct na zapis binarny będzie o tak:
7 | 3 | 1 |
111 | 011 | 001 |
111011001 |
Skoro już zaczęliśmy omawiać przejście z bazy większej do mniejszej, to potrenujmy to!
Problem drugi, przechodzenie z systemu o wyższej bazie na niższą:
Tak jak napisałem, przechodzenie z systemu o większej bazie do mniejszej, sprowadza się do dzielenia z resztą
1310 to będzie dwójkowo·
13/ 2 = 6 i 1 reszty·
6/2 = 3 i 0 reszty ·
3/2 = 1 i 1 reszty ·
1/2 = 0 i 1 reszty
Zapisujemy reszty od końca 1101.
Co tu się stało tak naprawdę?
Dziel i zwyciężaj!
13 to inaczej 1 * 20 + 12 <=> 1 * 20 + 0 * 21 + 12 <=> 1 * 20 + 0 * 21 + 1* 22 + 8 <=> 1 * 20 + 0 * 21 + 1* 22 + 1* 23
Wygląda znajomo?
innymi słowy, szukamy liczby 2x takiej by po odjęciu jej od naszej 13 była o jedną potęgę mniejsza od naszej liczby czyli 2n, a potem odejmujemy tak długo 2 do potęgi n-1 aż dostaniemy zero:)
24 to 16 wiec o oczko za dużo dlatego 23 to 8 się nada
U nas n będzie wynosiło 3, wiec odejmujemy kolejno potęgi dwójki, 23, 22,21,20, a gdyby tego było mało schodzimy do potęg ujemnych
13 – 23 = 5
Jedziemy kolejne odejmowanie czyli
22 Potem
21 a na koniec
20
5 – 22 =11 – 2 1 = -1 czyli tego nie chcemy dajemy 0
1 -20 = 0 idealnie 1
Jedziemy dalej 123 na system dwójkowy
Przed podzieleniem | Wynik | Reszta z dzielenia |
123 | 61 | 1 |
61 | 30 | 1 |
30 | 15 | 0 |
15 | 7 | 1 |
7 | 3 | 1 |
3 | 1 | 1 |
1 | 0 | 1 |
Wynik zapisujemy od końca 1111011
I na tym poprzestaniemy, na dzisiaj.
Za tydzień lekki temat, czyli zapis naukowy liczb dziesiętnych.
Za dwa tygodnie, powinniśmy w końcu dojść do tematu zapisu liczbowego w komputerach, oraz tego, dlaczego jest on tak nieprecyzyjny. Poznamy też dziwadła plus zero i minus zero.
PS
Tematem który nie poruszałem do tej pory, to system liczbowy addatywny. Polega on na tym że sumujemy kolejne znaki z sobą, np liczby rzymskie, należą do systemu addatywnego , ale też mamy system jedynkowy z którego korzystał nie mal każdy
| jedna kawa
|| dwie kawy
||| 3 kawy 🙂
||||| 5 kaw
Z kolei liczby rzymskie np XVII czyli 10 + 5 + 2 daje siedemnaście.
Fajne
Piszę, bo to istotne:
jest błąd w 1-szej tabeli – 14 (dec) i 15 (dec) to nie jest 20 (oct) i 21 (oct) tylko 16 (oct) i 17 (oct).
20 (oct) = 16 (dec)
zamiana 10tna na 16tkowy w ten sposób niestety powyżej 256 nie zadziała.