Podstawy arytmetyki komputerowej
Systemy liczbowe, bity, bajty, słowa, operatory logiczne, awans zmiennej, saturacja, przepełnienie. Krótka darmowa lekcja informatyki :)
VXER z- #
- #
- #
- #
- 3
- Odpowiedz
Systemy liczbowe, bity, bajty, słowa, operatory logiczne, awans zmiennej, saturacja, przepełnienie. Krótka darmowa lekcja informatyki :)
VXER zDla niektórych ten wpis może być tylko przypomnieniem, ale postanowiłem to jednak opisać. Rozpocznę od wyjaśnienia czym jest system liczbowy. System reprezentacji liczb pozwala zapisywać liczby z użyciem określonego zbioru znaków. Dwa bardzo ważne w informatyce systemy liczbowe oprócz dziesiętnego, którego używamy na co dzień to system binarny (dwójkowy) oraz heksadecymalny (szesnastkowy). Często w celu rozróżnienia w jakim systemie jest zapisana określona liczba używa się przedrostków i przyrostków. Liczby binarne przyjęło się zapisywać z przyrostkiem „b” np. 101000111b. Natomiast liczby w systemie heksadecymalnym zapisuje się z przyrostkiem h np. 02FFh lub z przedrostkiem 0x np. 0x2FF.
Nie chcę tutaj tworzyć na ten temat wywodu matematycznego. Na początek wystarczy, że początkujący czytelnicy, gdy zobaczą w programie zapis np. 0FFFFh to będą wiedzieć, że to liczba tylko inaczej zapisana (szesnastkowo). W systemie dwójkowym (binarnym) do zapisu określonej liczby używa się tylko dwóch znaków: zero (0) oraz jeden (1). Natomiast w systemie szesnastkowym (heksadecymalnym) do przedstawienia liczby używa się szesnastu znaków: od 0 do 9 oraz od A do F.
W tabeli poniżej przedstawiono przykładowe wartości liczbowe zapisane w trzech różnych systemach.
Do przeliczania wartości pomiędzy systemami liczbowymi można użyć systemowego kalkulatora. Wystarczy tylko przełączyć się w Tryb programisty.
Pamięć komputerowa posiada swoje jednostki miary. Najmniejsza jednostka informacji pamięci komputerowej to bit. Może mieć on wartość jeden lub zero.
Inne jednostki to:
Skrócone symbole określające poszczególne jednostki to: b – bit, B – bajt, KB – kilobajt, MB – megabajt etc.
Chyba w każdym języku programowania można spotkać operatory lub instrukcje logiczne operujące na bitach. Podstawowe operacje, które możemy przeprowadzić przedstawiono poniżej.
Wynik jest prawdziwy tylko wtedy, gdy dwa operandy są prawdziwe.
Wynik jest prawdziwy, jeśli chociaż jeden operand jest prawdziwy.
Wynik jest prawdziwy, jeśli jeden i tylko jeden operand jest prawdziwy.
Wynik jest odwróceniem operandu.
Operacje logiczne mogą być łączone. Na rysunku poniżej przedstawiono koniunkcję z zaprzeczonym pierwszym operandem.
Dla przykładu poniżej przedstawiono koniunkcję logiczną dla dwóch liczb binarnych.
W przypadku typów danych ze znakiem (ang. signed) przyjęto, że najstarszy bit jest nazywany bitem znaku. Jego wartość decyduje czy dana liczba jest dodatnia czy ujemna. Jeśli najstarszy bit jest ustawiony, to liczba traktowana jest jako ujemna, a w przeciwnym wypadku jako dodatnia. Określenie czy liczba binarna jest ze znakiem czy bez znaku zależne jest od interpretacji. Jeśli w bajcie (rozmiar 8 bitów) ustawimy wszystkie bity: 11111111b to przeliczając do systemu dziesiętnego będzie to wartość 255d bez znaku lub -1d w przypadku interpretacji jako typ ze znakiem.
Istnieją różne metody kodowania liczb binarnych ze znakiem, ale najbardziej naturalna jest metoda z uzupełnieniem do dwóch (U2). Poszczególne kroki dla przykładowej liczby -14 są następujące:
Warto wspomnieć też o terminie takim jak „zero ze znakiem”. W niektórych reprezentacjach liczb binarnych (np. uzupełnienie do jeden, czyli U1 czy też formaty zmiennoprzecinkowe np. IEEE 754) możliwe jest otrzymanie liczby zero z ustawionym bitem znaku. Wartość określana jest wtedy jako „ujemne zero” (ang. negative zero).
Rozszerzenie z zachowaniem znaku (ang. sign extension) może występować np. przy wpisaniu wartości o rozmiarze bajtu do rejestru lub zmiennej o rozmiarze słowa. Mechanizm jest bardzo prosty. Polega on na powieleniu bitu znaku na pozostałe (starsze) bity.
Na przykład:
-14d = 11110010b jako bajt,
-14d = 1111111111110010b jako słowo,
-14d = 11111111111111111111111111110010b jako podwójne słowo
etc.
Dopełnienie zerami (ang. zero extension) działa na zasadzie wpisania zer w starsze bity np. przy wpisaniu wartości o rozmiarze bajta do rejestru lub zmiennej większego rozmiaru.
Przepełnienie zmiennej całkowitej (ang. integer overflow) występuje, gdy wartość rezultatu obliczeń jest poza zakresem możliwym do przechowania przez określony typ danych. Maksymalna wartość jaką można zapisać na jednym bajcie (8 bitach) bez znaku to 255d (0FFh). Co zatem będzie jeśli wykonamy operację np. 253d + 5d? Wynik będzie równy 2d. Można to porównać do „przekręcenia” się licznika np. tak jak w starszych samochodach.
Poniżej trzy przykłady dla operacji na danych o rozmiarze jednego bajta:
Binarnie wyglądałoby to następująco:
Awans zmiennej to proces w którym typ danych, który posiada mniejszy zakres wartości (np. bajt) jest zamieniany na taki o większym zakresie (np. int) podczas operacji arytmetycznej. Dzięki temu operacja nie wywołuje przepełnienia (ang. overflow). Na rysunku przedstawiono przykład w Visual C++. Mnożenie dwóch bajtów o wartościach 20 oraz 64 daje w wyniku 1280. Wartość ta nie zmieści się w bajcie, który ma tutaj zakres od 0 do 255. Podczas obliczeń następuje awans zmiennej. Dalej jest podzielenie 1280 przez 10, co daje w wyniku 128. Wartość ta mieści się w zmiennej o rozmiarze bajta i zostaje poprawnie wyświetlona przez funkcję printf.
Saturacja polega na ustaleniu limitu, przedziału wartości dla danej zmiennej. Jeśli wynik jest większy niż górny limit (maksimum) to przyjmuje wartość maksymalną. W przypadku, gdy wynik jest mniejszy niż minimum, to przyjmuje wartość minimalną. Pozwala to częściowo uchronić przed błędnym działaniem programu i warto to stosować.
Na przykład jeśli ustalimy dla zmiennej limit wartości od -64 do 64 to poniższe operacje dadzą następujące wyniki:
Nie zawsze w obliczeniach komputerowych wynikiem jest liczba. Sądzę, że nawet nieodpowiednią rzeczą byłoby np. zwracanie zawsze zero, jeśli wynik jest nieprawidłowy. Wartość NaN (Not a Number) jest często spotykana w obliczeniach zmiennoprzecinkowych (ang. floating-point). Standard kodowania takich liczb (IEEE 754) definiuje taką wartość jak właśnie NaN, a także inne nietypowe wartości jak np. nieskończoność (±INFINITE). Wartość NaN według formatu IEEE 754 posiada w wykładniku same jedynki, a w mantysie wartość różną od zera.
Dziękuję za czas poświęcony na przeczytanie tego wpisu.
Artykuł jak i rysunki są mojego autorstwa.
Źródło: https://haker.info/blog/details/podstawy-arytmetyki-komputerowej
Komentarze (3)
najlepsze
W tym przypadku bit, jeśli ma być informacją, to powinien być definiowany jako relacja pomiędzy stanem zero, a jeden.