2. Arytmetyka komputera. Systemy zapisu liczb: dziesietny, dwójkowy (binarny), ósemkowy, szesnatskowy. Podstawowe operacje arytmetyczne na liczbach binarnych. Zapis liczby binarnej ze znakiem. Reprezentacja stało- i zmiennopozycyjna. SYSTEMY LICZBOWE System liczbowy jest zbiorem reguł określających jednolity sposób zapisu i nazewnictwa liczb. Systemy liczbowe pozycyjne. - jedynkowy system liczbowy - dwójkowy system liczbowy - siódemkowy system liczbowy - ósemkowy system liczbowy - dziesiętny system liczbowy - dwunastkowy system liczbowy - szesnastkowy system liczbowy - sześćdziesiątkowy system liczbowy System jedynkowy. System jedynkowy jest najprostszym systemem zapisu liczb. System ten wykorzystuje do zapisu liczb tylko cyfrę 1. 111 = 1*1 0 + 1*1 1 + 1*1 2 = 1*1 + 1*1 + 1*1 = 1 + 1 + 1 = 3 System dwójkowy (binarny). Ponieważ liczby w pamięci komputera reprezentowane są przy użyciu bitów, dlatego w informatyce stosuje się dwójkowy system liczbowy. W
tym systemie podstawą jest liczba 2. Do zapisu liczb potrzebne są dwie cyfry: 0 i 1. 1100101 = 1*2 0 + 0*2 1 + 1*2 2 + 0*2 3 + 0*2 4 + 1*2 5 + 1*2 6 = 1*1 + 0*2 + 1*4 + 0*8 + 0*16 + 1*32 + 1*64 = 1+ 0+ 4+ 0+ 0+ 32+ 64 = 101 Zamiana liczb dziesiętnych na system binarny. Zamianę tę przeprowadzamy dzieląc z resztą liczbę dziesiętną przez 2, pamiętając o późniejszym "wyrzuceniu" zbędnych zer z lewej strony np.: (0010110) 2 = (0010110) 2 = (10110) 2 (583) 10 = (1001000111) 2 System siódemkowy. Nazywany również systemem septymalnym. Do zapisu liczb używa się siedmiu cyfr: 0-6 System ósemkowy. Do zapisu liczb w tym systemie wykorzystuje się 8 cyfr: 0, 1, 2, 3, 4, 5, 6, 7 Podstawą jest liczba 8. Cyfrę stojącą na pierwszej pozycji mnożymy
razy 8 0, cyfrę na 2 pozycji mnożymy razy 8 1, cyfrę na 3 pozycji mnożymy razy 8 2 itd. 174 = 4*8 0 + 7*8 1 + 1*8 2 = 4*1 + 7*8 + 1* 64 = 4+ 56+ 64 = 124 (174) 8 = (124) 10 System dziesiętny. Jest to podstawowy system liczbowy stosowany w większości krajów świata. Do zapisu liczb w tym systemie wykorzystuje się 10 cyfr: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Podstawą pozycji są kolejne potęgi liczby 10. Zapis liczb wygląda jak poniżej: cyfrę stojącą na pierwszej pozycji mnożymy razy 10 0. Cyfrę na 2 pozycji mnożymy razy 10 1, cyfrę na 3 pozycji razy 10 2 itd. 4123 = 3*10 0 + 2*10 1 + 1*10 2 + 4*10 3 = 3*1 + 2*10 + 1*100 + 4*1000 = 3 + 20 + 100 + 4000 = 4123 System dwunastkowy. Liczby zapisuje się tu jako ciągi cyfr, z których każda jest mnożnikiem kolejnej potęgi liczby stanowiącej podstawę systemu, np. liczba zapisana w dziesiętnym systemie liczbowym jako 1000, w dwunastkowym przybiera postać 6B4, gdyż: 6 12 2 + 11 12 1 + 4 12 0 = 864 + 132 + 4 = 1000 System szesnastkowy. Ze względu na specyfikę architektury komputerów, gdzie często najszybszy dostęp jest do adresów parzystych, albo podzielnych przez 4, 8 czy 16, często używany jest szesnastkowy system liczbowy. Sprawdza się on szczególnie przy zapisie dużych liczb takich jak adresy pamięci, zakresy parametrów itp. Do zapisu liczb w systemie szesnastkowym wykorzystuje się 16 znaków (10 cyfr i 6 liter): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. gdzie: A=10, B=11, C=12, D=13, E=14, F=15 Podstawą w systemie szesnastkowym są kolejne potęgi liczny 16. D3A = 10*16 0 + 3*16 1 + 13*16 2 = 10*1 + 3*16 + 13*256 = 10 + 48 + 3328 = 3386 System szesnastkowy często spotykany jest też na stronach WWW (HTML), gdzie stosowany jest do zapisu kolorów.
#FFFFFF - kolor biały System szesnastkowy jest również stosowany w przypadku użycia kodów ASCII. Znaki są często podawane przy użyciu dwucyfrowych liczb szesnastkowych. Natomiast ludzkie przyzwyczajenie do operowania w systemie dziesiątkowym jest tak ugruntowane, że żaden inny system pozycyjny nie może mieć szerszego znaczenia w komunikacji między ludźmi. System sześćdziesiątkowy. Jest to pozycyjny system liczbowy o podstawie 60. Był używany w Babilonie i to już w 1750 p.n.e., stąd dotarł do Europy. Układ sześćdziesiątkowy obecnie jest używany w oznaczaniu jednostek czasu. Godzina dzieli się na 60 minut, minuta na 60 sekund. Zamiana liczb hexadecymalnych na binarne i odwrotnie. BIN HEX BIN HEX 0000 0 1000 8 0001 1 1001 9 0010 2 1010 A 0011 3 1011 B 0100 4 1100 C 0101 5 1101 D 0110 6 1110 E
0111 7 1111 F System dwójkowy dobrze pasuje do maszyny, gdyż reprezentacja jednej cyfry zajmuje dokładnie jeden bit. n-cyfrowa liczba (bez znaku) pamiętana jest w słowie n-bitowym. Natomiast dla człowieka jest on zbyt rozwlekły. Dodawanie liczb binarnych. Główne zasady przy dodawaniu liczb binarnych: 0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 0 (+1 dodajemy do następnej pozycji) 1 1 1 0 0 1 1 (3) 10 + 0 1 0 1 (5) 10 1 0 0 0 (8) 10 Odejmowanie liczb binarnych.
Odejmowanie liczb binarnych wykonuje się poprzez zamianę jednej z liczb na ujemną. Odejmowanie jest więc dodawaniem ujemnych liczb binarnych. Liczby binarne można zapisać w postaci ujemnej stosując niżej opisaną zasadę zamiany liczby binarnej dodatniej na ujemną: Zapis: Uzupełnienie do 1 - U1, czyli: (10110100) 2 = (01001011) U1 Wszystkie bity przepisujemy z zaprzeczeniem. Uzupełnienie do 1 liczby binarnej jest zawsze negacją bitów tej liczby. 2-3 = -1-3 + 2 = -1 2 = 010 3 = 011-3 = 100 bity znaku 1 0 0 + 0 1 0 1 1 0 otrzymaliśmy wynik z bitem znaku 1 (liczba ujemna), a należy dokonać ponownie zamiany U1 pomijając bit znaku 1 0 1 otrzymujemy 01 z bitem znaku 1 wynikiem jest więc liczba -1 ponieważ -3 + 2 = -1
Mnożenie liczb binarnych bez znaku. 1 0 1 1 mnożnik (11) x 1 1 0 1 mnożnik (13) 1 0 1 1 0 0 0 0 1 0 1 1 iloczyny cząstkowe 1 0 1 1 1 0 0 0 1 1 1 1 iloczyn 143 10001111 = 1*2 0 + 1*2 1 + 1*2 2 + 1*2 3 + 0*2 4 + 0*2 5 + 0*2 6 + 1*2 7 = 1 + 2 + 4 + 8 + 0 + 0 + 0 + 128 = 143 Dzielenie liczb binarnych. Dzielenie binarne jest to najbardziej skomplikowana operacja arytmetyczną na liczbach binarnych. W poniższym przykładzie oparto się na metodzie, która polega na cyklicznym odejmowaniu odpowiednio przesuniętego dzielnika od dzielnej. W systemie dwójkowym jest to szczególnie proste, ponieważ dzielnika nie musimy mnożyć. Podzielimy liczbę (1110) 2 przez (11) 2 czyli (14:3) 10 :
Przesuwamy dzielnik w lewo, aż jego najstarszy niezerowy bit zrówna się z najstarszym, niezerowym bitem dzielnej. Nad dzielną rysujemy kreskę: 1110 11 dzielna przesunięty dzielnik Jeżeli możliwe jest odjęcie dzielnika od dzielnej bez niedomiaru, to nad kreską w kolumnie najmłodszego bitu dzielnika wpisuje się 1 i wykonuje odejmowanie: 1 1 1 1 0 dzielna 1 1 przesunięty dzielnik 0 0 1 0 różnica dzielnej i przesuniętego dzielnika W następnym kroku dzielnik przesuwa się o jeden bit w prawo i próbuje się tej samej operacji z otrzymaną różnicą. Jeśli odejmowanie jest możliwe, to nad kreską w następnej kolumnie dopisuje się 1, następnie odejmuje się dzielnik od różnicy, przesuwa się go o 1 bit w prawo i kontynuuje się działania. Jeśli odejmowanie nie jest możliwe, to dopisuje się nad kreską 0, przesuwa się dzielnik o 1 bit w prawo i kontynuuje. 1 0 0 wynik dzielenia 1 1 1 0 dzielna
- 1 1 dzielnik 0 0 1 0 dzielna po odejmowaniu przesuniętego dzielnika - 1 1 dzielnika nie można odjąć 0 0 1 0 dzielna po odejmowaniu przesuniętego dzielnika - 1 1 dzielnika nie można odjąć 0 0 1 0 reszta z dzielenia Wyżej opisane operacje wykonuje się do czasu, aż dzielnik osiągnie swoją pierwotną wartość. Pozostała dzielna jest resztą z dzielenia. W powyższym przykładzie otrzymano wynik (100) 2 i resztę (10) 2, tzn. (4 i 2) 10. Wynik ten jest poprawny. 3 mieści się w 4 cztery razy, pozostaje reszta 2. Reprezentacja stałopozycyjna liczb całkowitych. Zapis liczb ujemnych. Liczby całkowite ze znakiem są pamiętane w słowach n-bitowych. Ustalmy n=8.
Nieujemna liczba całkowita jest pamiętana jako znak i moduł liczby zapisany w systemie dwójkowym. Powyższe słowo reprezentuje liczbę 77. Natomiast jeśli liczba jest ujemna to istnieje kilka sposobów jej reprezentacji: 1. znak-moduł: wygodny dla człowieka, ale przy operacjach arytmetycznych trzeba porównywać znaki i 0 ma dwie reprezentacje ('dodatnią' i 'ujemną'). 2. znak-uzupełnienie do 1: ta reprezentacja jest mniej wygodna dla człowieka i w niej też 0 ma dwie reprezentacje. To, że 0 ma dwie reprezentacje nie jest tylko sprawą estetyki. Gdy jeden obiekt ma równe reprezentacje, sprawdzenie równości dwóch obiektów staje się niepotrzebnie skomplikowana procedurą. 3. znak-uzupełnienie do 2: ta reprezentacja jest jeszcze mniej wygodna dla człowieka ale w niej 0 (i każda inna reprezentowana liczba) ma tylko jedną reprezentację, ponadto operacje arytmetyczne są wykonywane w prosty sposób. Ze względu na przytoczone powyżej zalety zajmiemy się bliżej sposobem reprezentacji liczb jako znak-uzupełnienie do 2. Ten jest w praktyce używany do reprezentacji liczb całkowitych w komputerach. Uzupełnienie do 1 liczb całkowitych otrzymujemy negując wszystkie bity. x = 10011000 u1 = 01100111 Uzupełnienie do 2 liczb całkowitych otrzymujemy negując wszystkie bity i dodając 1. Dla x jak wyżej uzupełnienie do 2 liczby x jest równe:
x = 10011000 u1 = 01100111 0 1 1 0 0 1 1 1 + 1 0 1 1 0 1 0 0 0 Reprezentacja liczb całkowitych w systemie znak uzupełnienie do 2 (n = 8): dla 0 x 127
dla -128 x -1 (80) 10 0 1 0 1 0 0 0 0 (-48) 10 1 1 0 1 0 0 0 0 Reprezentując liczby w systemie znak - uzupełnienie do 2, przy dodawaniu nie trzeba zwracać uwagi na znak liczby. Wyniki otrzymujemy poprawne i dokładne o ile argumenty i wartości mają swoje reprezentacje jako słowa n-bitowe w systemie znak - uzupełnienie do 2. Zmiana znaku uzupełnienia do 2 liczby (łącznie z bitem znaku) w zapisie n - bitowym:
(26) 10 0 0 0 1 1 0 1 0 (-26) 10 1 1 1 0 0 1 1 0 Dodawanie dwóch liczb w systemie znak uzupełnienie do 2. Dodajemy liczby łącznie z bitem znaku i ewentualne przeniesienie pomijamy. Wynik reprezentuje sumę w systemie znak - uzupełnienie do 2: x = (24) 10 0 0 0 1 1 0 0 0 y = (- 1 1 0 1 1 0 0 0 48) 10 x + y = (- 1 1 1 1 0 0 0 0 16) 10 Aby umożliwić również zapis liczb ułamkowych, musimy rozszerzyć wagi pozycji w stronę ujemnych potęg podstawy. Część ułamkową
oddzielimy od części całkowitej zapisu za pomocą znaku przecinka. waga p n-1 p 2 p 1 p 0, p -1 p -2 p -m cyfry a n-1 a 2 a 1 a 0, a -1 a -2 a -m Wbrew pozorom obliczenie wartości tak zapisanej liczby wcale nie jest trudniejsze. Zasada nie zmienia się i musimy sumować kolejne iloczyny wartości cyfr przez wartości wag pozycji. Obliczenia rozpoczynamy od pierwszej pozycji po prawej stronie. a n-1... a 2 a 1 a 0 a -1 a -2... a -m = a -m p -m +...+ a -2 p -2 + a 0 p 0 + a 1 p 1 +a 2 p 2 +...+a n-1 p n-1 W przypadku liczb binarnych p=2. Przykład Obliczyć wartość liczby dwójkowej (11101,011) 2 (11101,011) 2 = 1 * 2-3 + 1 * 2-2 + 0 * 2-1 + 1 * 2 0 + 0 * 2 1 + 1 * 2 2 + 1 * 2 3 + 1 * 2 4 (11101,011) 2 = 1 * 1/8 + 1 * 1/4 + 0 * 1/2 + 1 * 1 + 0 * 2 + 1 * 4 + 1 * 8 + 1 * 16 (11101,011) 2 = 1/8 + 1/4 + 1 + 4 + 8 + 16 (11101,011) 2 = 29 3/8 = 29,375 Zamiana ułamka dziesiętnego na wartość binarną Metoda zamiany jest dwuetapowa. Najpierw zamieniana jest część całkowita ułamka. Wtedy stosuje się cykliczne dzielenie przez 2 i sprawdzanie reszty z dzielenia. Następnie zamienia się część ułamkową. Zamiana polega na cyklicznym mnożeniu ułamka razy 2 i sprawdzaniu, czy wynik nie jest większy lub równy 1. Jeżeli jest >= 1 to wyznaczony bit części ułamkowej jest także równy jeden. Do dalszych obliczeń bierze się część ułamkową wyniku. Czasem zamiana części ułamkowej na postać binarną prowadzi do osiągnięcia nieskończenie długiej kombinacji zer i jedynek. Dlatego zawsze należy przyjąć dodatkowy warunek - ile bitów jest przeznaczone na zapis części ułamkowej. Obliczenia wykonuje się wtedy dotąd, aż osiągnie się potrzebną liczbę bitów.
Zamienić liczbę 12 14/20 na postać binarną 8-bitową, gdzie przecinek jest po czterech bitach (4b,4b). 12 14/20 = 12,7 stąd: (12,7) 10 = (1100,1011) 2 Zapis zmiennopozycyjny Z zapisem zmiennoprzecinkowym można spotkać się w przypadkach, gdzie przy jego pomocy przedstawia się albo bardzo duże wartości, albo bardzo małe. Zapis ten nazywa się często notacją naukową, np.:
Gwiazda Proxima Centauri znajduje się w odległości 9460800000000 [km], czyli 9,4608 * 10 12. Masa elektronu wynosi m e = 0,00000000000000000000000000091095 [g], czyli 9,1095 * 10-28 [g] Liczba zapisana w systemie zmiennoprzecinkowym składa się z dwóch części: liczby stałoprzecinkowej, której wartość bezwzględna jest mniejsza od wartości podstawy systemu pozycyjnego oraz z podstawy podniesionej do pewnej potęgi zwanej wykładnikiem lub cechą. Wartość liczby jest równa iloczynowi części stałoprzecinkowej i wykładniczej: w = m * p e, m - mantysa, p - podstawa systemu, e - wykładnik potęgowy. Obliczanie wartości dwójkowej liczby zmiennoprzecinkowej Przyjmijmy następujące ustalenia. Dwójkowa liczba zmiennoprzecinkowa zbudowana jest z dwóch części: z mantysy m i wykładnika potęgowego e (zwanego również cechą). Ponieważ podstawa systemu liczenia jest znana i wynosi 2, więc nie ma potrzeby umieszczać jej w zapisie liczby. Mantysa m jest liczbą stałoprzecinkową na moduł mniejszą od 1. Wykładnik e jest liczbą całkowitą. Obie części mogą być zapisane np. w kodzie U2 lub kodzie ZM. Wartość liczby liczymy wg wzoru: w = m * 2 e Obliczenia Niech wykładnik zbudowany będzie z n bitów. Ponieważ jest to liczba całkowita, więc jej wartość obliczamy w poznany wcześniej sposób: czyli zgodny z zapisem dla liczb w kodzie U2 Mantysa ma być ułamkiem mniejszym na moduł od 1. Jeśli jest zbudowana z m bitów, to waga najstarszego bitu wynosi w kodzie U2-2 0, czyli
-1. Następna pozycja ma wagę 2-1, czyli 1/2, itd. Rozpiszmy to następująco: m = a n-1, a n-2 a n-3...a 2 a 1 a 0 = a n-1 (-2 0 ) + a n-2 2-1 + a n-3 2-2 +... + a 2 2 -n+3 + a 1 2 -n+2 + a 0 2 -n+1 Dla przykładowej, 4-bitowej mantysy wzór ten przyjmie następującą postać: m = a 3, a 2 a 1 a 0 = a 3 (-2 0 ) + a 2 2-1 + a 1 2-2 + a 0 2-3 m = a 3, a 2 a 1 a 0 = a 3 * -1 + a 2 * 1/2 + a 1 * 1/4 + a 0 * 1/8 m = a 3, a 2 a 1 a 0 = - a 3 + a 2 / 2 + a 1 / 4 + a 0 / 8 Liczba 8-bitowa, po 4 bity na mantysę i wykładnik 00110111 ZP =...? D Najpierw wydobywamy z liczby wykładnik e i mantysę m: 0 0 1 1 0 1 1 1 e m Teraz obliczamy kolejno wartość wykładnika i mantysy: e = 0011 U2 = 0 * (-8) + 0 * 4 + 1 * 2 + 1 * 1 e = 0011 U2 = 2 + 1 e = 0011 U2 = 3 D m = 0,111 U2 = - 0 + 1/2 + 1/4 + 1/8 m = 0,111 U2 = 1/2 + 1/4 + 1/8 m = 0,111 U2 = 4/8 + 2/8 + 1/8 m = 0,111 U2 = 7/8
Mając e i m, podstawiamy do wzoru i otrzymujemy 00110111 ZP = 7 D Obliczanie reprezentacji zmiennoprzecinkowej Mamy określony format zapisu liczby zmiennoprzecinkowej w systemie dwójkowym. Wiemy, że wykładnik ma zawierać n - bitów w kodzie U2, a cecha m bitów w zapisie stałoprzecinkowym U2. Przykład prostego systemu zmiennoprzecinkowego, w którym wykładnik i cecha mają po 4 bity długości. Przykładową liczbą niech będzie wartość 56: 56 D = 111000 B = 0111000 U2 - dodajemy zero, aby zaznaczyć, iż jest to liczba dodatnia. Zapiszemy wzór obliczeniowy, a następnie będziemy przesuwać w prawo cyfry mantysy dodając jednocześnie 1 do wykładnika, aż znacząca jedynka znajdzie się na pozycji o wadze 1/2. 0111000,000 U2 =2 0000U2 011100,000 U2 =2 0001U2 - przesuwamy cyfry mantysy w prawo, zwiększamy wykładnik 01110,000 U2 =2 0010U2 0111,000 U2 =2 0011U2 011,100 U2 =2 0100U2 01,110 U2 =2 0101U2 0,111 U2 =2 0110U2 - kończymy, mantysa jest znormalizowana Otrzymujemy więc: e = 0110 = 6 D m = 0,111 = 7/8, sprawdzamy: 7/8 x 2 6 = 448/8 = 56
Obliczenia dla liczby 254: (254) 10 = (11111110) 2 = (01111111) u2 011111110,0000000 = 2 0000000 przesuwamy o 8 miejsc (8) 10 = (1000) 2 stąd: m = 0,11111110 e = 1000 sprawdzamy: (½ + ¼ + 1/8 + 1/16 + 1/32 + 1/64 + 1/128) * 2 8 = (127/128) * 256 = 254.