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 |
©2024 mgr Jerzy Wałaszek
|
Pierwszą rzeczą do zrozumienia jest pojęcie informacji. Czym jest informacja? Okazuje się, że dokładna odpowiedź na to pytanie jest dosyć trudna. Oczywiście powstają różne definicje na potrzeby różnych nauk. Nam jednak chodzi o rozumienie intuicyjne. Cechą charakterystyczną informacji jest to, że nie można podać jakiejś jednej, ściśle określonej postaci informacji. Dlatego, iż informacja jest interpretowana w naszych mózgach jako coś, co zmniejsza naszą niepewność w określonej sytuacji. Dla jednych coś może być informacją, dla innych to samo może nic nie znaczyć. Przykładem mogą być czasy wojenne. W konspiracji używano różnych znaków do porozumiewania się w grupie wtajemniczonych, które dla osób z poza tej grupy nie przekazywały żadnego znaczenia. Np. mężczyzna stojący na rogu ulicy zdejmuje z głowy czapkę, jakby się komuś kłaniał. Jest to sygnał dla pozostałych, że nadjeżdża niemiecka ciężarówka, którą zaraz należy zaatakować. Osoba postronna tej informacji nie odbierze.
Aby doszło do przekazania informacji muszą być spełnione pewne warunki.
W procesie przekazania informacji mamy nadawcę N oraz odbiorcę O. Nie muszą to być wcale ludzie. W elektronice obu często zastępują komputery.
Nadawca i odbiorca muszą znajdować się we wspólnym ośrodku, który umożliwia przesyłanie informacji. W przykładzie z II Wojny Światowej członek ruchu oporu sygnalizujący grupie uderzeniowej przyjazd ciężarówki musi być przez tę grupę widziany, inaczej cały system na nic. Jeśli ktoś chce przekazać coś głosem, to musi być słyszany.
Nadawca wysyła informację, odbiorca ją odbiera.
Jeśli sądzisz, że to wszystko, to niestety jesteś w błędzie. Diabeł jak zwykle tkwi w szczegółach. Teraz należy uzgodnić w jaki sposób ta informacja ma być wysyłana, czyli jaką ma przybrać postać: mowa, pismo, gesty, sygnały radiowe, światło lasera, prąd elektryczny, itd. Innymi słowy musimy zdefiniować sobie fizyczny zbiór sygnałów, które będą używane do przesyłania wiadomości. Dodatkowo odbiorca musi wiedzieć, jak zinterpretować otrzymany sygnał. Czyli sygnałom należy przypisać odpowiednie znaczenia.
Wynika z tego następująca procedura postępowania:
Jakie sygnały wybrać? Nie jest to wcale takie oczywiste. Pierwsze maszyny cyfrowe operowały na cyfrach dziesiętnych. Jednak komplikowało to ich konstrukcję. W roku 1936 niemiecki konstruktor Konrad Zuse zbudował pierwszy na świecie komputer oparty na nowych sygnałach - na bitach. Sama nazwa bit powstała dużo później. Bit jest najprostszym z możliwych sygnałów. Występuje tylko w dwóch różniących się od siebie postaciach. O tym, jaką postać przyjmują bity, decyduje ośrodek oraz realizacja techniczna. Przykłady realizacji bitów są następujące:
BIT (ang. binary digit – cyfra dwójkowa) | |
Postać pierwsza | Postać druga |
Jest prąd w przewodzie | Brak prądu w przewodzie |
Napięcie 2,4...5V | Napięcie 0,2...0,8V |
Fala radiowa 5MHz | Fala radiowa 7MHz |
Jest światło lasera | Brak światła lasera |
Litera H (ang. high) | Litera L (ang. Low) |
Cyfra 1 | Cyfra 0 |
Wewnątrz komputera bity najczęściej są reprezentowane poziomami napięć, które przetwarzają cyfrowe układy elektroniczne. Do zapisu bitów w elektronice stosuje się litery H/L, gdzie H oznacza stan wysoki (np. 5V), a L oznacza stan niski (np. 0,4V). W informatyce bity oznaczamy cyframi 1 i 0. 1 odpowiada poziomowi H, a 0 odpowiada poziomowi L.
Powstaje teraz problem: jak kodować informację za pomocą bitów? Pokażemy to na przykładach.
Jeden bit może przyjmować tylko jedną z dwóch wartości. Jeśli tą wartość potraktujemy jako wiadomość, to za pomocą jednego bitu będziesz mógł kodować dwie różne wiadomości:
Bit 1: wiadomość pierwsza Bit 0: wiadomość druga |
Jakie to mogą być wiadomości? Takie, jakie będziesz potrzebował. Na przykład:
Bit 1: przycisk nie jest naciśniety Bit 0: przycisk jest naciśnięty |
Albo:
Bit 1: silnik pracuje Bit 0: silnik nie pracuje |
Skąd będzie wiadomo, co dany bit oznacza? Jeśli przeczytałeś dokładnie to, co napisałem powyżej, to rozumiesz, że takie rzeczy nie są dane z góry, tylko się je ustala. Konstruując układ z mikrokontrolerem, sam określisz znaczenia różnych bitów. Co więcej, ten sam bit w innym układzie może posiadać zupełnie inne znaczenie. Wszystko zależy od konstrukcji układu elektronicznego i to ty będziesz decydował, co w tym układzie znaczą przetwarzane bity.
Jeden bit jest małą jednostką. Co zrobić, gdy liczba wiadomości jest większa od 2? Odpowiedź jest prosta: bity łączysz w grupy i traktujesz taką grupę jak jeden sygnał. Jeśli połączysz ze sobą dwa bity, to otrzymasz 4 różne sygnały bitowe:
00: sygnał nr 1 01: sygnał nr 2 10: sygnał nr 3 11: sygnał nr 4 |
Cztery sygnały, to cztery wiadomości. Dla 3 bitów otrzymasz już 8 sygnałów, czyli będziesz w stanie działać na 8 różnych wiadomościach:
000: sygnał nr 1 001: sygnał nr 2 010: sygnał nr 3 011: sygnał nr 4 100: sygnał nr 5 101: sygnał nr 6 110: sygnał nr 7 111: sygnał nr 8 |
Dodając następny bit, otrzymasz 16 sygnałów. Każdy następny bit podwaja liczbę sygnałów:
2 → 4 → 8 → 16 → 32 |
Zwróć uwagę, że jest to ciąg potęg liczby 2. Wykładnik potęgi określa liczbę bitów w sygnale:
liczba bitów | liczba sygnałów | potęga 2 |
1 | 2 | 21 |
2 | 4 | 22 |
3 | 8 | 23 |
4 | 16 | 24 |
5 | 32 | 25 |
... | ... | ... |
8 | 256 | 28 |
... | ... | ... |
16 | 65536 | 216 |
... | ... | ... |
32 | 4294967296 | 232 |
... | ... | ... |
64 | 18446744073709551616 | 264 |
... | ... | ... |
Ciąg ten nie ma końca. Dla każdej skończonej liczby wiadomości zawsze możemy dobrać tyle bitów w paczce, aby otrzymać pożądaną liczbę sygnałów. Na tym spostrzeżeniu opiera się cała współczesna technika cyfrowa.
Dlaczego wybrano akurat bity na jednostki informacji w komputerach? Odpowiedź jest prosta: pieniądze. Bity są proste, zatem przetwarzające je układy również są proste (w miarę), a zatem tanie w produkcji. Dodatkowo bity są bardziej odporne na zakłócenia od innych sygnałów. A na koniec, i tak przetwarzają je komputery, a nie my, ludzie. Więc co nam to szkodzi?
W pamięci komputera bity zapamiętuje się w paczkach po 8. Taką grupę ośmiu bitów nazywamy bajtem (ang. byte). Bity oznaczamy małą literą b, a bajty dużą literą B. Jeden bajt może przyjąć 256 różnych kombinacji swoich bitów.
W informatyce stosujemy następujące jednostki informacji:
bit | b | – | najmniejsza jednostka, dwa stany 0 i 1 |
kilobit | Kb | – | 1024 bity |
megabit | Mb | – | 1024 Kb = 1048576 b |
bajt | B | – | grupa 8 bitów, 256 stanów od 00000000 do 11111111 |
kilobajt | KB | – | 1024 B |
megabajt | MB | – | 1024 KB = 1048576 B |
gigabajt | GB | – | 1024 MB = 1048576 KB = 1073741824 B |
terabajt | TB | – | 1024 GB = 1048576 MB = 1073741824 KB = 1099511627776 B |
petabajt | PB | – | 1024 TB = 1048576 GB = 1073741824 MB = 1099511627776 KB = 1125899906842624 B |
Jednostki wielokrotne odpowiadają w przybliżeniu jednostkom stosowanym w fizyce, jednak w informatyce oparte są one na potęgach liczby 2, a nie na potęgach liczby 10:
kilo | K | – | 210 |
mega | M | – | 220 |
giga | G | – | 230 |
tera | T | – | 240 |
peta | P | – | 250 |
Dlaczego pojawia się tutaj liczba 2? Komputery są maszynami binarnymi. Potęgi liczby 2 są dla nich bardziej naturalne od potęg liczby 10 i lepiej wpisują się w ich architekturę.
W celu zaznaczenia tej różnicy, wielokrotności informatyczne pisze się dużą literą.
Cyfrowe urządzenia wyświetlają grafikę w postaci tzw. rastra:
Raster jest siatką punktów graficznych, które mogą przybierać różne kolory. Nazywamy je pikselami (ang. pixel = picture element – element obrazu). Piksele są zwykle tak małe, że oko ich nie zauważa jako osobny element obrazu – wyjątkiem są proste wyświetlacze o małej rozdzielczości, jak na powyższych obrazkach.
Załóżmy, że chcemy zakodować przy pomocy bitów poniższy obrazek:
W tej skali piksele nie są dobrze widoczne. Powiększy zatem ten obrazek, a uzyskamy widok tworzących go pikseli:
Tutaj wyraźnie widać, że piksele są tylko dwóch rodzajów: biały i czarny. Informacją do zakodowania jest właśnie kolor pikseli. Dwa kolory wymagają jednego bitu. Zróbmy następujące przypisanie:
– bit 0 | |
– bit 1 |
Teraz można już zakodować kolor każdego piksela obrazka za pomocą bitów. Powstanie tzw. mapa bitowa, czyli odwzorowanie pikseli w bity:
0000111111110000 |
Co zrobić w przypadku, gdy bity muszą przybierać więcej niż dwa kolory? Odpowiedzieliśmy na to pytanie w poprzednim podrozdziale: należy wziąć grupę bitów. Niech nasz obrazek wygląda następująco:
Powiększmy go odpowiednio, aby zobaczyć piksele:
Piksele na tym obrazku przyjmują cztery różne kolory. Mamy zatem do zakodowania cztery wiadomości o kolorze każdego piksela. Potrzebne są grupy dwubitowe:
- 00 | |
- 01 | |
- 10 | |
- 11 |
Po przetworzeniu na bity powstaje mapa bitowa:
00000000010101010101010100000000 |
Jeśli kolorów jest więcej, to po prostu kodujemy je słówkami zbudowanymi z większej liczby bitów. Są to sprawy techniczne związane z implementacją grafiki. Poniższy obrazek jest zbudowany z pikseli o 256 kolorach, czyli każdy piksel jest kodowany za pomocą 8 bitów (u dołu obrazka pokazana jest paleta użytych kolorów):
Tzw. grafikę True color (prawdziwy kolor) tworzą piksele kodowane za pomocą 24 bitów, co daje paletę 16 milionów kolorów. W programach graficznych stosuje się grafikę nawet 48 bitową (w celu uzyskania płynnych przejść tonalnych na profesjonalnych wydrukach).
Do zapisu liczb oraz do obliczeń ludzie stosują tzw. system dziesiętny, który rozpowszechnił się w Europie w czasach średniowiecza za sprawą kupców arabskich, którzy przywieźli go z Indii. Genialność tego systemu polega na tym, iż za pomocą skończonej liczby symboli można zapisywać dowolne liczby. O wszystkim tym uczyłeś się w szkole, jednak uporządkujmy tę wiedzę.
W systemie dziesiętnym mamy dziesięć cyfr: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Liczby zapisujemy za pomocą ciągu tych cyfr (na razie pominiemy przecinek dziesiętny). Jednakże w zapisie tym cyfry posiadają różne wagi w zależności od swojej pozycji. Ostatnia pozycja ma wagę 1, poprzedzająca ją pozycja ma wagę 10, kolejne 100, 1000, 10000... Każda następna pozycja ma wagę 10 razy większą. Liczba 10 pełni ważną funkcję w tym systemie – nazywamy ją podstawą systemu. Dla przykładu zapiszmy pewną liczbę dziesiętną:
wagi: | ... |
103 1000 |
102 100 |
101 10 |
100 1 |
cyfry: | ... | 4 | 7 | 3 | 5 |
pozycje: | ... | 3 | 2 | 1 | 0 |
Zwróć uwagę, że waga pozycji ma wartość równą podstawie podniesionej do potęgi numeru pozycji. Cyfry informują nas, ile razy waga pozycji występuje w liczbie. I tak w naszej liczbie mamy 4 tysiące, 7 setek, 3 dziesiątki oraz 5 jednostek. Matematycznie wartość tej liczby można obliczyć mnożąc cyfry przez wagi ich pozycji i dodając otrzymane iloczyny:
4735 = 4 · 103 + 7 · 102
+ 3 · 101
+ 5 · 100 4735 = 4 · 1000 + 7 · 100 + 3 · 10 + 5 · 1 |
Z pozoru rachunki te mogą ci się wydać bezsensowne. Masz rację, w systemie dziesiętnym nie ma to wielkiego sensu. Jednak zasada obliczania wartości liczby będzie również obowiązywała, jeśli zmienimy podstawę, np. na 5. Co się w tedy stanie? Otrzymamy system piątkowy, w którym występuje tylko 5 cyfr: 0, 1, 2, 3, 4. Dlaczego? Wynika to z konstrukcji systemu pozycyjnego. W systemie dziesiętnym też nie mamy cyfr o wartościach większych od 9 (podstawa - 1). Zatem w systemie piątkowym liczby będziemy zapisywali za pomocą tylko tych pięciu cyfr. Zmianie ulegną również wagi pozycji, które teraz będą potęgami liczby 5, czyli nowej podstawy. Zapiszmy jakąś liczbę piątkową:
wagi: | ... |
53 125 |
52 25 |
51 5 |
50 1 |
cyfry: | ... | 3 | 4 | 2 | 4 |
pozycje: | ... | 3 | 2 | 1 | 0 |
Wszystkie systemy pozycyjne zbudowane są wg takiego samego schematu. Cyfry oznaczają zawsze liczbę wag pozycji, które wchodzą w skład liczby. Tutaj mamy:
3424(5)
= 3 · 53 + 4 · 52 + 2 · 51
+ 4 · 50 3424(5) = 3 · 125 + 4 · 25 + 2 · 5 + 4 · 1 3424(5) = 375 + 100 + 10 + 4 3424(5) = 489 |
Indeks przy liczbie informuje, że jest to liczba piątkowa i należy jej cyfry interpretować wg wag piątkowych, a nie dziesiętnych. W naszym systemie, liczba ta ma wartość 489. W systemie piątkowym można zapisywać wszelkie liczby równie dobrze jak w systemie dziesiętnym.
Jeśli za podstawę systemu przyjmiemy 2, to otrzymamy system dwójkowy zwany również systemem binarnym (ang. binary system). Ilość cyfr zredukuje się do 2: 0 i 1. Wagi pozycji będą teraz potęgami liczby 2.
wagi: | ... |
23 8 |
22 4 |
21 2 |
20 1 |
cyfry: | ... | 1 | 1 | 0 | 1 |
pozycje: | ... | 3 | 2 | 1 | 0 |
Wartość liczby dwójkowej obliczamy identycznie jak wartość liczby w dowolnym innym systemie pozycyjnym (mnożymy cyfry przez ich wagi i dodajemy te iloczyny):
1101(2) = 1 · 23
+ 1 · 22 + 0 · 21 + 1 · 20 1101(2) = 1 · 8 + 1 · 4 + 0 · 2 + 1 · 2 1101(2) = 8 + 4 + 0 + 1 1101(2) = 13 |
W systemie dwójkowym jest nawet prościej niż w innych systemach, ponieważ waga albo występuje w liczbie (cyfra 1), albo nie występuje (cyfra 0). Zatem wcale nie trzeba nic mnożyć: wystarczy zsumować wagi tych pozycji, na których stoi cyfra 1. Wagi można dla ułatwienia sumować od końca zapisu liczby, wtedy kolejne wagi otrzymamy przez podwojenie wagi poprzedzającej, zaczynając od 1:
111010101(2)
= 1 + 4 + 16 + 64 + 128 + 256 111010101(2) = 469 |
Cyfry liczby dwójkowej można reprezentować bezpośrednio bitami. Co więcej, nazwa bit oznacza właśnie cyfrę dwójkową: (ang. binary digit).
Kodowanie tekstu nie różni się od kodowania kolorów pikseli w grafice. Tam kodowaną informacją był kolor piksela, tutaj kodowaną informacją będzie litera, a właściwie symbol drukarski. Koncepcja jest taka, aby każdemu znakowi przypisać inny kod bitowy. Istnieje wiele praktycznych systemów kodowania znaków. Mikrokontrolery najczęściej stosują kody ASCII, ponieważ są one 8-bitowe, a, jak zobaczymy dalej, jest to podstawowy rozmiar jednostki pamięci w mikrokontrolerach 8-bitowych.
|
|
|
|
Podstawowy zestaw znaków ASCII kodowany jest za pomocą 7 najmłodszych bitów. Kod bitowy znaku masz w kolumnie BIN (ang. binary – dwójkowo). Wartość kodu jako liczba dziesiętna znajduje się w kolumnie DEC. Zwróć uwagę, że pierwszy bit (zwany najstarszym lub najbardziej znaczącym bitem – ang. msb = most significant bit) jest w tych kodach ustawiony na 0. Kod znaku potraktowany jak liczba daje wartości od 0 (00000000) do 127 (01111111). Jeśli przyjrzysz się tej tabeli, to zauważysz, że znaki nie są ułożone w niej chaotycznie, tylko w 4 grupach:
0 | 0 | 0 | x | x | x | x | x |
znaki sterujące |
Pierwszą grupę kodów ASCII tworzą tzw. znaki sterujące (ang. control characters). Posiadają one różne znaczenia w zależności od urządzenia, do którego zostaną przesłane. Zwykle powodują jakieś działanie, np. przejście do początku następnego wiersza (znak LF i CR). W konsoli ekranowej niektóre z tych znaków mogą być wydrukowane, dając dodatkowe symbole. W przypadku mikrokontrolerów znaki będziesz wysyłał do różnych wyświetlaczy. Musisz dokładnie sprawdzić w instrukcji wyświetlacza, jaką funkcję realizują znaki z tej grupy kodów.
0 | 0 | 1 | 1 | x | x | x | x |
cyfry |
Cyfry mają kody od 48 (00110000) do 57 (00110000). Zwróć uwagę, iż po odjęciu liczby 48 od kodu ASCII cyfry (albo wyzerowaniu 4 najstarszych bitów) otrzymasz kod równy wartości tej cyfry:
kod ASCII | kod ASCII - 48 | |||
BIN | DEC | Znak | BIN | DEC |
00110000 | 48 | 0 | 00000000 | 0 |
00110001 | 49 | 1 | 00000001 | 1 |
00110010 | 50 | 2 | 00000010 | 2 |
00110011 | 51 | 3 | 00000011 | 3 |
00110100 | 52 | 4 | 00000100 | 4 |
00110101 | 53 | 5 | 00000101 | 5 |
00110110 | 54 | 6 | 00000110 | 6 |
00110111 | 55 | 7 | 00000111 | 7 |
00111000 | 56 | 8 | 00001000 | 8 |
00111001 | 57 | 9 | 00001001 | 9 |
Odwrotnie też zadziała. Jeśli do wartości cyfry dodasz liczbę 48, to otrzymasz kod ASCII znaku tej cyfry. Informacje te są istotne, gdy spróbujesz samodzielnie napisać funkcje wypisujące liczby na wyświetlaczu lub w oknie konsoli. W dalszej części kursu pokażę, jak to się robi.
Litera A: kod 65 65 + 32 = 97 Litera a: kod 97 |
Jeśli od kodu małej litery odejmiesz 32, to otrzymasz kod litery dużej. Spostrzeżenie to przyda ci się, gdy będziesz potrzebował zamieniać znaki w tekście z małych na duże lub odwrotnie. Bitowo kody małych i dużych liter różnią się tylko jednym bitem, b5:
Duże litery | Małe litery | ||||
BIN | DEC | Litera | BIN | DEC | Litera |
01000001 | 65 | A | 01100001 | 97 | a |
01000010 | 66 | B | 01100010 | 98 | b |
01000011 | 67 | C | 01100011 | 99 | c |
... | ... | ... | ... | ... | ... |
W kodach dużych liter bit b5 ma wartość 0, w kodach małych liter bit b5 ma wartość 1.
0 | x | x | x | x | x | x | x | 1 | x | x | x | x | x | x | x | |
podstawowy kod ASCII |
rozszerzony kod ASCII |
Oprócz podstawowego zestawu 128 kodów ASCII (0...127) używa się również kodów rozszerzonych (128...255). W kodach podstawowych najstarszy bit, b7 ma wartość 0. W kodach rozszerzonych bit ten ma wartość 1. W rozszerzonym zestawie znaków ASCII są zdefiniowane znaki narodowe oraz różne dodatkowe znaki graficzne, np. do tworzenia tabelek. Tutaj mogą pojawić się kody polskich znaków, jednak w różnych standardach są to różne kody. Np. standard konsoli Windows (tzw. Latin II lub CP852) obsługuje następujące znaki rozszerzone:
znak(128) = Ç znak(160) = á znak(192) = └ znak(224) = Ó znak(129) = ü znak(161) = í znak(193) = ┴ znak(225) = ß znak(130) = é znak(162) = ó znak(194) = ┬ znak(226) = Ô znak(131) = â znak(163) = ú znak(195) = ├ znak(227) = Ń znak(132) = ä znak(164) = Ą znak(196) = ─ znak(228) = ń znak(133) = ů znak(165) = ą znak(197) = ┼ znak(229) = ň znak(134) = ć znak(166) = Ž znak(198) = Ă znak(230) = Š znak(135) = ç znak(167) = ž znak(199) = ă znak(231) = š znak(136) = ł znak(168) = Ę znak(200) = ╚ znak(232) = Ŕ znak(137) = ë znak(169) = ę znak(201) = ╔ znak(233) = Ú znak(138) = Ő znak(170) = ¬ znak(202) = ╩ znak(234) = ŕ znak(139) = ő znak(171) = ź znak(203) = ╦ znak(235) = Ű znak(140) = î znak(172) = Č znak(204) = ╠ znak(236) = ý znak(141) = Ź znak(173) = ş znak(205) = ═ znak(237) = Ý znak(142) = Ä znak(174) = « znak(206) = ╬ znak(238) = ţ znak(143) = Ć znak(175) = » znak(207) = ¤ znak(239) = ´ znak(144) = É znak(176) = ░ znak(208) = đ znak(240) = znak(145) = Ĺ znak(177) = ▒ znak(209) = Đ znak(241) = ˝ znak(146) = ĺ znak(178) = ▓ znak(210) = Ď znak(242) = ˛ znak(147) = ô znak(179) = │ znak(211) = Ë znak(243) = ˇ znak(148) = ö znak(180) = ┤ znak(212) = ď znak(244) = ˘ znak(149) = Ľ znak(181) = Á znak(213) = Ň znak(245) = § znak(150) = ľ znak(182) = Â znak(214) = Í znak(246) = ÷ znak(151) = Ś znak(183) = Ě znak(215) = Î znak(247) = ¸ znak(152) = ś znak(184) = Ş znak(216) = ě znak(248) = ° znak(153) = Ö znak(185) = ╣ znak(217) = ┘ znak(249) = ¨ znak(154) = Ü znak(186) = ║ znak(218) = ┌ znak(250) = ˙ znak(155) = Ť znak(187) = ╗ znak(219) = █ znak(251) = ű znak(156) = ť znak(188) = ╝ znak(220) = ▄ znak(252) = Ř znak(157) = Ł znak(189) = Ż znak(221) = Ţ znak(253) = ř znak(158) = × znak(190) = ż znak(222) = Ů znak(254) = ■ znak(159) = č znak(191) = ┐ znak(223) = ▀ znak(255) = |
Polskie litery w różnych standardach mają kody:
Ą | Ć | Ę | Ł | Ń | Ó | Ś | Ź | Ż | ą | ć | ę | ł | ń | ó | ś | ź | ż | |
Windows 1250 | 165 | 198 | 202 | 163 | 209 | 211 | 140 | 143 | 175 | 185 | 230 | 234 | 179 | 241 | 243 | 156 | 159 | 191 |
CP852 | 164 | 143 | 168 | 157 | 227 | 224 | 151 | 141 | 189 | 165 | 134 | 169 | 136 | 228 | 162 | 152 | 171 | 190 |
Różne kodowanie polskich znaków jest przyczyną kłopotów przy wyświetlaniu tekstu w Windows (Linux stosuje konsekwentnie standard ISO-8852-2 w całym systemie). Gdy pracujesz w edytorze, polskie znaki są kodowane wg standardu Windows-1250. Gdy uruchamiasz swój program, to pracuje on wg CP852, jednakże do konsoli wciąż wysyła kody Windows 1250, ponieważ tak było w programie źródłowym. Załóżmy, że chcesz wypisać w konsoli wyraz żółć. Co otrzymasz:
Litera | Windows 1250 | CP852 |
ż | 191 | ┐ |
ó | 243 | ˇ |
ł | 179 | │ |
ć | 230 | Š |
Zamiast słówka żółć w oknie konsoli pojawi się ┐ˇ│Š. Podobnie może być w mikrokontrolerach, jeśli obsługiwany wyświetlacz działa w innym systemie kodowania polskich liter niż edytor. Musisz na to zwrócić w przyszłości uwagę, jeśli zechcesz obsługiwać w swoim programie język polski. Cóż, standardy są dla wielkich, małymi nikt się nie przejmuje.
Liczby są podstawowym elementem przy programowaniu. Dlatego znajomość ich kodowania uważam za kluczową. W tym podrozdziale omówię podstawowe systemy kodowania liczb. Wcześniej podałem sposób kodowania liczb za pomocą bitów. Przypomnijmy:
Liczby kodujemy w systemie dwójkowym za pomocą dwóch cyfr 0 i 1. Wagi pozycji są kolejnymi potęgami liczby 2. Wartość liczby jest sumą wag pozycji zawierających cyfrę 1:
wagi: | ... |
28 128 |
26 64 |
25 32 |
24 16 |
23 8 |
22 4 |
21 2 |
20 1 |
cyfry: | ... | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
pozycje: | ... | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
11001011(2) = 1 + 2 + 8 + 64 + 128 = 203 |
Taki sposób zapisu liczb nosi nazwę naturalnego kodu binarnego czyli NBC (ang. Natural Binary Code). Kod NBC umożliwia kodowanie jedynie liczb dodatnich i zera. Jeśli chcemy również kodować liczby ujemne, to stosujemy tzw. kod uzupełnień do 2, zwany kodem U2. Kod U2 jest bardzo podobny do NBC, jedyną różnicą jest to, iż waga najstarszego bitu jest ujemna. Dzięki temu uzyskujemy możliwość kodowania liczb ujemnych. Zasada obliczania wartości liczby U2 jest identyczna jak dla liczby NBC: liczba jest sumą wag pozycji zawierających cyfry 1:
wagi: | ... |
-28 -128 |
26 64 |
25 32 |
24 16 |
23 8 |
22 4 |
21 2 |
20 1 |
cyfry: | ... | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
pozycje: | ... | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
01001011(2) = 1 + 2 + 8 + 64 = 113 |
wagi: | ... |
-28 -128 |
26 64 |
25 32 |
24 16 |
23 8 |
22 4 |
21 2 |
20 1 |
cyfry: | ... | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
pozycje: | ... | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
01001011(2) = 1 + 2 + 8 + 64 - 128 = -15 |
Najstarszy bit w liczbie U2 nosi nazwę bitu znaku (ang. sign bit). Jeśli bit znaku ma wartość 0, to liczba jest dodatnia, ponieważ żadna z pozostałych wag nie jest ujemna. Jeśli bit znaku ma wartość 1, to liczba jest ujemna, ponieważ suma pozostałych wag nie równoważy wartości wagi ujemnej.
Liczby są przechowywane w pamięci komputera w postaci określonej liczby bitów. Najczęściej będzie to: 8, 16, 32 i 64 bity. Im więcej bitów w liczbie, tym większy zakres wartości może ona przybierać.
Policzmy zakres liczb NBC:
Najmniejszą wartość uzyskamy, gdy wszystkie bity będą zerami. Wtedy wartość liczby wynosi 0, ponieważ nie zawiera ona żadnej wagi.
Największą wartość otrzymamy, gdy wszystkie bity będą jedynkami. Wtedy każda waga wchodzi do liczby. Jaką wartość przyjmuje liczba NBC, jeśli składa się z n jedynek? Spójrz poniżej:
Ilość bitów | Liczba NBC | Wartość | Związek | |
1 | 1 | 1 | 2 - 1 | 21 - 1 |
2 | 11 | 3 | 4 - 1 | 22 - 1 |
3 | 111 | 7 | 8 - 1 | 23 - 1 |
4 | 1111 | 15 | 16 - 1 | 24 - 1 |
5 | 11111 | 31 | 32 - 1 | 25 - 1 |
6 | 111111 | 63 | 64 - 1 | 26 - 1 |
7 | 1111111 | 127 | 128 - 1 | 27 - 1 |
8 | 11111111 | 255 | 256 - 1 | 28 - 1 |
... | ... | ... | ... | ... |
16 | 1111...1111 | 65535 | 216 - 1 | |
... | ... | ... | ... | |
32 | 1111...1111 | 4294967295 | 232 - 1 | |
... | ... | ... | ... | |
64 | 1111...1111 | 18446744073709551615 | 264 - 1 | |
... | ... | ... | ... | |
n | 1111...1111 | 2n - 1 |
W tabelce podane są wartości liczb binarnych zbudowanych z coraz większej liczby jedynek. Zauważamy, że wartość takiej liczby jest równa 2n - 1, gdzie n oznacza ilość jedynek. Na tej podstawie zapisujemy, że zakres n bitowych liczb w kodzie NBC jest równy:
0 ... 2n - 1 |
A teraz liczby U2. Najmniejszą wartość uzyskamy, gdy bit znaku będzie ustawiony na 1, a wszystkie pozostałe bity będą równe 0. Wartość takiej liczby składa się tylko z wagi ujemnej.
Ilość bitów | Liczba U2 | Wartość | Związek | |
1 | 1 | -1 | -(20) | -(21-1) |
2 | 10 | -2 | -(21) | -(22-1) |
3 | 100 | -4 | -(22) | -(23-1) |
4 | 1000 | -8 | -(23) | -(24-1) |
5 | 10000 | -16 | -(24) | -(25-1) |
6 | 100000 | -32 | -(25) | -(26-1) |
7 | 1000000 | -64 | -(26) | -(27-1) |
8 | 10000000 | -128 | -(27) | -(28-1) |
... | ... | ... | ... | ... |
16 | 1000...0000 | -32768 | -(215) | -(216-1) |
... | ... | ... | ... | ... |
32 | 1000...0000 | -2147483648 | -(231) | -(232-1) |
... | ... | ... | ... | ... |
64 | 1000...0000 | -9223372036854775808 | -(263) | -(264-1) |
... | ... | ... | ... | ... |
n | 1000...0000 | -(2n-1) |
Liczba U2 przyjmuje największą wartość, gdy bit znaku jest ustawiony na 0, a wszystkie pozostałe bity mają wartość 1. Wtedy wartość liczby zawiera wszystkie wagi dodatnie.
Ilość bitów | Liczba U2 | Wartość | Związek | |
1 | 0 | 0 | 20 - 1 | 21-1 - 1 |
2 | 01 | 1 | 21 - 1 | 22-1 - 1 |
3 | 011 | 3 | 22 - 1 | 23-1 - 1 |
4 | 0111 | 7 | 23 - 1 | 24-1 - 1 |
5 | 01111 | 15 | 24 - 1 | 25-1 - 1 |
6 | 011111 | 31 | 25 - 1 | 26-1 - 1 |
7 | 0111111 | 63 | 26 - 1 | 27-1 - 1 |
8 | 01111111 | 127 | 27 - 1 | 28-1 - 1 |
... | ... | ... | ... | ... |
16 | 0111...1111 | 32767 | 215 - 1 | 216-1 - 1 |
... | ... | ... | ... | ... |
32 | 0111...1111 | 2147483647 | 231 - 1 | 232-1 - 1 |
... | ... | ... | ... | ... |
64 | 0111...1111 | 9223372036854775807 | 263 - 1 | 264-1 - 1 |
... | ... | ... | ... | ... |
n | 0111...1111 | 2n-1 - 1 |
I ostatecznie otrzymujemy zakres n bitowej liczby U2:
-(2n-1)...2n-1 - 1 |
Porównajmy zakresy liczb NBC i U2 w typowych formatach:
Ilość bitów | Zakres NBC | Zakres U2 |
4 | 0...15 | -8...7 |
8 | 0...255 | -128...127 |
12 | 0...4095 | -2048...2047 |
16 | 0...65535 | -32768...32767 |
32 | 0...4294967295 | -2147483648...2147483647 |
64 | 0...18446744073709551615 | -9223372036854775808...9223372036854775807 |
W systemie ósemkowym podstawa wynosi 8 i do zapisu liczby stosujemy 8 cyfr od 0 do 7. Ponieważ liczba 8 jest potęgą liczby 2 (8 = 23), to istnieje bardzo prosty sposób konwersji pomiędzy systemem ósemkowym a dwójkowym (konwersja polega na zapisaniu tej samej liczby w innym systemie liczbowym). Będzie potrzebna tabela wartości cyfr ósemkowych w systemie dwójkowym:
Cyfra ósemkowa | Wartość dwójkowa |
0 | 000 |
1 | 001 |
2 | 010 |
3 | 011 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
Naucz się na pamięć tej tej tabelki lub zapamiętaj, że cyfrze ósemkowej zawsze będzie odpowiadała trzybitowa liczba NBC o wartości tej cyfry.
Liczbę dwójkową konwertujemy na ósemkową następująco:
01111110100100010001000111(2) |
Dzielimy ją na grupy po 3 bity poczynając od prawej strony:
01 111 110 100 100 010 001 000 111 |
Jeśli ostatnia grupa nie zawiera 3 bitów, to uzupełniamy je bitami 0 do trójki:
001 111 110 100 100 010 001 000 111 |
Każdą trójkę bitów zastępujemy odpowiadającą jej cyfrą ósemkową z tabelki:
001 | 111 | 110 | 100 | 100 | 010 | 001 | 000 | 111 |
1 | 7 | 6 | 4 | 4 | 2 | 1 | 0 | 7 |
Konwersja skończona:
01111110100100010001000111(2) = 176442107(8) |
Otrzymana w ten sposób liczba ósemkowa posiada dokładnie taką samą wartość jak wyjściowa liczba dwójkowa. Czytelność liczby ósemkowej jest dużo większa od odpowiadającej jej liczby dwójkowej.
W odwrotną stronę postępujemy podobnie:
2607531(8) |
Zamieniamy każdą jej cyfrę na grupę 3 bitów zgodnie z tabelką:
2 | 6 | 0 | 7 | 5 | 3 | 1 |
010 | 110 | 000 | 111 | 101 | 011 | 001 |
Konwersja skończona:
2607531(8) = 010110000111101011001(2) |
Gdy nabierzesz wprawy, będziesz wykonywał taką konwersję w locie.
Cyfra szesnastkowa | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
Wartość cyfry | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Do konwersji używamy tabelki zamiany cyfr szesnastkowych na bity. Każda cyfra szesnastkowa odpowiada 4 bitom. Naucz się tej tabelki na pamięć:
Cyfra szesnastkowa | Wartość dwójkowa |
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 |
Konwersji dokonujemy podobnie jak przy konwersji ósemkowej:
01111110100100010001000111(2) |
Dzielimy ją na grupy po 4 bity poczynając od prawej strony:
01 1111 1010 0100 0100 0100 0111 |
Jeśli ostatnia grupa nie zawiera 4 bitów, to uzupełniamy je bitami 0 do czwórki:
0001 1111 1010 0100 0100 0100 0111 |
Każdą czwórkę bitów zastępujemy odpowiadającą jej cyfrą szesnastkową z tabelki:
0001 | 1111 | 1010 | 0100 | 0100 | 0100 | 0111 |
1 | F | A | 4 | 4 | 4 | 7 |
Konwersja skończona:
01111110100100010001000111(2) = 1FA4447(16) |
W drugą stronę:
6FB87A3(16) |
Zamieniamy każdą jej cyfrę na grupę 4 bitów zgodnie z tabelką:
6 | F | B | 8 | 7 | A | 3 |
0110 | 1111 | 1011 | 1000 | 0111 | 1010 | 0011 |
Konwersja skończona:
6FB87A3(16) = 0110111110111000011110100011(2) |
Liczby szesnastkowe lepiej oddają wartości dwójkowe przetwarzane przez komputer niż liczby ósemkowe. Na przykład bajt można ładnie przedstawić za pomocą dwóch cyfr szesnastkowych (4 + 4 bity). Natomiast liczba ósemkowa bajt musi zakodować za pomocą 3 cyfr (2 + 3 + 3 bity).
Kod U2 pozwala zapisywać liczby całkowite dodatnie, ujemne oraz liczbę zero.
Jak zapisać za pomocą bitów liczby ułamkowe, które są potrzebne do różnych obliczeń naukowych? Reguły kodowania liczb ułamkowych wymyślono dawno temu. Już w roku 1936 Konrad Zuse zbudował pierwszy na świecie komputer dwójkowy, który pracował z takimi właśnie liczbami. Aby zrozumieć sposób zapisu liczb ułamkowych, posłużmy się liczbami dziesiętnymi. Przecinek rozdziela część całkowitą od ułamkowej:
wagi: | ... |
103 1000 |
102 100 |
101 10 |
100 1 |
10-1 1/10 |
10-2 1/100 |
10-3 1/1000 |
10-4 1/10000 |
... | |
cyfry: | ... | 2 | 7 | 1 | 5 | , | 3 | 2 | 9 | 4 | |
pozycje: | ... | 3 | 2 | 1 | 0 | -1 | -2 | -3 | -4 | ... | |
część całkowita |
część ułamkowa |
2 · 103 + 7 · 102 + 1 · 101 + 5 · 100 + 3 · 10-1 + 2 · 10-2 + 9 · 10-3 + 4 · 10-4 |
Cyfry po lewej stronie przecinka określają część całkowitą liczby. Ich pozycje numerujemy kolejno od zera w górę w kierunku z prawa na lewo. Wagi pozycji całkowitych są potęgami podstawy o wykładniku równym numerowi pozycji.
Cyfry po lewej stronie przecinka określają część ułamkową liczby. Ich pozycje numerujemy od -1 w kierunku coraz większych liczb ujemnych. Zwróć uwagę, że jest to zupełnie naturalne przedłużenie numeracji pozycji obecnej po stronie całkowitej. Wagi pozycji w części ułamkowej również są potęgami podstawy o wykładnikach równych numerom pozycji, tylko teraz te wykładniki to liczby ujemne. Z matematyki wiemy, że:
Stąd otrzymujemy wagi ułamkowe: 0,1 0,01 0,001 ... Zasada obliczania wartości liczby nie ulega zmianie: mnożymy cyfry przez ich wagi i sumujemy otrzymane iloczyny.
W systemie dwójkowym jest dokładnie tak samo. Zmieniają się tylko wartości wag pozycji, które teraz będą potęgami liczby 2, a nie 10.
wagi: | ... |
23 8 |
22 4 |
21 2 |
20 1 |
2-1 1/2 |
2-2 1/4 |
2-3 1/8 |
2-4 1/16 |
... | |
cyfry: | ... | 1 | 1 | 0 | 1 | , | 1 | 1 | 0 | 1 | |
pozycje: | ... | 3 | 2 | 1 | 0 | -1 | -2 | -3 | -4 | ... | |
część całkowita |
część ułamkowa |
||||||||||
1101,1101(2) = 8
+ 4 + 1 + 1/2 + 1/4
+ 1/16 1101,1101(2) = 13 + 13/16 1101,1101(2) = 13,8125 |
Taki zapis liczby nosi nazwę zapisu stałoprzecinkowego (ang. fixed point notation). Jeśli chcemy zakodować liczbę w tym systemie, musimy określić pozycję przecinka, ponieważ nie jest on bitem i nie można go sobie tak wstawić pomiędzy cyfry dwójkowe. Po prostu liczbę 1101,1101 zapisujemy w pamięci jako 11011101, lecz pamiętamy, że ostatnie cztery bity są bitami ułamkowymi.
Z zapisem zmiennoprzecinkowym spotkałeś się na pewno na fizyce, gdy należało zapisać jakieś bardzo duże lub bardzo małe liczby. Na przykład:
2,4 · 1067 |
Zwróć uwagę, że tak zapisana liczba składa się faktycznie z trzech osobnych liczb:
2,4 – mantysa m, określa
wartość podstawową liczby 10 – podstawa systemu zapisu liczb p 67 – cecha c, określa wykładnik Wartość liczby liczymy jako m · pc. |
Liczba tak zapisana nosi nazwę liczby zmiennoprzecinkowej (ang. floating point number). Dlaczego? Zmieniając odpowiednio mantysę i cechę możemy ustawić przecinek w dowolnym miejscu:
2,4 · 1067 = 0,24 · 1068 = 0,024 · 1069 = 24,0 · 1066 = 240 · 1065 = ... |
Dlatego umówiono się, że liczby takie będą zawsze prezentowane w postaci znormalizowanej, tzn. takiej, iż mantysa ma wartość pomiędzy 1 a 10. Z liczby zmiennoprzecinkowej wystarczy zapamiętać mantysę i cechę, ponieważ wiemy, że podstawą systemu dziesiętnego jest 10. Zatem w postaci znormalizowanej nasza liczba może być zapisana jako:
2,4 67 |
Niektóre kalkulatory w ten właśnie sposób prezentują liczby zmiennoprzecinkowe (zwane również inżynierskimi lub naukowymi):
-1,234567809 · 10-35 |
Jak odnieść to do systemu dwójkowego? Prosto: w kodzie liczby należy zapamiętać cechę oraz znormalizowaną mantysę. Tutaj przyjęto, iż znormalizowana mantysa ma wartość mniejszą 1. Wagi mantysy dwójkowej są następujące:
wagi: | ... |
2-1 1/2 |
2-2 1/4 |
2-3 1/8 |
2-4 1/16 |
... |
cyfry: | ... | 0/1 | 0/1 | 0/1 | 0/1 | ... |
pozycje: | ... | -1 | -2 | -3 | -4 | ... |
Na początku dodajemy jeden bit znaku:
bit znaku 0 – mantysa jest dodatnia bit znaku 1 – mantysa jest ujemna |
Oprócz mantysy w kodzie liczby zostaje również umieszczona cecha, np. jako liczba U2. Dla przykładu stwórzmy taki "szkolny" kod zmiennoprzecinkowy. Umówmy się, że pierwsze cztery bity będą określały cechę liczby w kodzie U2, kolejny bit będzie bitem znaku mantysy, a ostatnie trzy bity będą reprezentowały mantysę:
wagi: |
-(23) -8 |
22 4 |
21 2 |
20 1 |
|
2-1 1/2 |
2-2 1/4 |
2-3 1/8 |
|||||||||
cyfry: | c | c | c | c | z | m | m | m | |||||||||
cecha | mantysa | ||||||||||||||||
|
Załóżmy, że mamy następujący kod:
00100101 |
Rozdzielamy go na części składowe:
0010 0 101 0010 – cecha = 2 0 – bit znaku, mantysa dodatnia 101 – bity ułamkowe mantysy, 1/2 + 1/8 = 5/8 |
Obliczamy wartość:
m · pc = 5/8 · 22 = 5/8 · 4 = 5/2 = 2,5 |
Inny przykład:
11011111 1101 1 111 1101 – cecha = -8 + 4 + 1 = -3 1 – bit znaku, mantysa ujemna 111 – bity ułamkowe mantysy, m = -(1/2 + 1/4 + 1/8) = -(7/8) |
Obliczamy wartość:
m · pc = -(7/8) · 2-3 = -(7/8) · 1/8 = -(7/64) = -0,109375 |
Liczba bitów mantysy określa tzw. precyzję liczby. Im tych bitów
więcej, tym dokładniej można odwzorować daną wartość rzeczywistą. W naszym
przykładowym systemie zmiennopozycyjnym mantysa posiada długość 3 bitów. Pozwala
ona zakodować tylko takie liczby binarne, które można sprowadzić do tych 3 bitów
przez usunięcie zer wiodących lub końcowych: np.:
Liczba bitów cechy wpływa na zakres wartości. Im tych bitów więcej, tym większy jest zakres liczb zmiennoprzecinkowych.
Zagadnienia związane z liczbami zmiennoprzecinkowymi są trudne dla początkujących. Dlatego zakończymy ich opis w tym miejscu, aby nie zanudzać cię zbędnymi ci w tym momencie szczegółami technicznymi. Jeśli chcesz wiedzieć więcej na ten temat, to proponuję ci przeczytanie artykułu o binarnym kodowaniu liczb.
Zapraszamy do następnego rozdziału.
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 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.