Arytmetyka stało- i zmiennoprzecinkowa 1. Informacje wstępne Każdą informację można przedstawid w komputerze za pomocą łaocucha elemantarnych jednostek, zwanych bitami. W przypadku, gdy chcielibyśmy wyrazid pewną liczbę możemy posłużyd się również interpretacją arytmetyczną złożoną z liczb 0 oraz 1. Odpowiednio skonstruowana liczba zapisana zostaje wówczas w systemie dwójkowym. Komputer przetwarza jednak ciągi bitów o określonej długości. Są to wektory bitowe. W ten sposób 8 bitów tworzy bajt. Nazewnictwo większych jednostek uzależnione jest od architektury maszyny przetwarzającej te dane. Mają one wspólną nazwę słowo maszynowe (np. CISC 16 bitów; RISC 32 bity). Wszystkie dane przetwarzane przez komputer możemy zaklasyfikowad do jednej z trzech grup: - kody rozkazów (opcode) - dane systemowe (system structured data) - dane użytkowe (user defined data) W tym przypadku interesuje nas ta trzecia grupa danych użytkowe. Są one najbardziej różnorodnym zestawem danych. Możemy je podzielid na dane: - skalarne - strukturalne - wskaźnikowe Typy skalarne z kolei można podzielid na: - jakościowe lub wyliczeniowe - dyskretne, w tym właśnie stałoprzecinkowe - pseudorzeczywiste, w tym zmiennoprzecinkowe Na bazie podstawowych typów danych język programowania może może definiowad inne, własne typy. Nadany zmiennej typ obowiązuje w zakresie działania deklaracji danej. Jest to również powiązane z ustaleniem sposobu wykonywania działao na danej. Zamiana typu danej wymaga jawnej konwersji, często jest automatyczna określona przez typ zmiennej docelowej. Tak się dzieje w maszynie wirtualnej (język programowania), ale w maszynie rzeczywistej nie ma takich etykiet zmiennych. Typ danej zawartej w słowie maszynowym jest jednoznacznie określony przez użytą operację i powiązane z nią argumenty (implikacja kontekstowa). Standardowymi typami implikowanymi kontekstowo są: typ całkowity, typ naturalny, typ logiczny oraz typ zmiennoprzecinkowy. 2. Kodowanie Każdy bit wspomnianego wektora bitowego ma swój numer pozycji. Numerowanie bitów od pozycji skrajnie prawej to interpretacja wektora bitów jako liczby naturalnej w w binarnym systemie pozycyjnym. Bit najmniej znaczący ma numer zero. Do skróconego zapisu liczb stosuje się notacji hexadecymalnej. Dane liczbowe o wielkości słowa maszynowego to dane pojedynczej precyzji. Dane składające się z większej ilości słów to dane rozszerzonej precyzji zgodnie z jedną z konwencji little endian lub big endian. Dane strukturalne są złożeniem pól bitowych, z których każdy może mied inną interpretację. Tę formę mają kody reprezentacji zmiennoprzecinkowych.
3. Typ Porządkowy naturalny (Naturalny kod binarny) NBC (ang: Natural Binary Code) - naturalny kod binarny jest to system pozycyjny o podstawie 2. Określone w nim liczby są bez znaku. Kolejne liczby naturalne w 2-bitowym NKB wyglądają następująco: Dec Bin(NBC) 0 00 1 01 2 10 3 11 Wartośd = 4. Typ całkowity (Kod uzupełnieniowy U2) Aby móc reprezentowad liczbę całkowitą należy zagwarantowad, aby w przestrzeni kodowej możliwa była zmiana znaku liczby. Przestrzeo ta jest jednak symetryczna, a liczba kodów parzysta, możliwe zatem jest jedno z dwóch rozwiązao prezentacji przestrzeni: z podwójną reprezentacją zera lub wystąpi niewielka asymetria zakresu. Można zatem osobno kodowad znaki + oraz -. Wartośd liczby zapisuje się wówczas tak jak w NKB, a znak liczby określa najbardziej znacząca pozycja. 0 dla liczb dodatnich, 1 dla ujemnych: X = gdzie s to wartośd bitu najbardziej znaczącego, a wartością bitu na i-tej pozycji. Inny sposób jest następujący. Liczba ujemna jest przeciwieostwem artymetycznym liczby dodatniej i odwrotnie. Zatem w systemie pozycyjnym o podstawie β zasadna jest definicja reprezentacji liczby ujemnej jako wektora dopełnieo. Wówczas liczby { } oraz { } są sobie przeciwne. W systemie dwójkowym zatem dopełnieniu cyfry odpowiada negowanie bittów reprezentacji, bo (1-x) = ~x. Ponieważ (x-1) = -x + 1, więc reprezentację kolejnej liczby ujemnej (czyli o wartości bezwzględnej mniejszej o 1) otrzymujemy dodając 1 do liczby poprzedniej. Jest to system U1, czyli uzupełnieniowy do jedynki. Zero ma w nim dwie reprezentacje: 0 0 oraz 1 1. Istnieje również system uzupełnieniowy pełny. W tym przypadku reprezentacje liczb dodatnich są takie same jak liczb w naturalnym kodzie binarnym. Reprezentację liczby -1 otrzymamy poprzez odjęcie wartości 1 od 0. Jest to właściwie podstawą arytmetycznej metody konstrukcji reprezentacji liczb całkowitych. W dwójkowym systemie uzupełnieniowym (U2) arytmetyczny porządek kodów liczb jest zachowany w całym zakresie liczb. Kody liczb dodatnich rozpoczynają się od bitu 0, a ujemnych od 1. Wówczas jeśli : { } reprezentuje dodatnią liczbę X, to { } jest kodem liczby ujemnej większej o X od najmniejszej liczby. Wartośd liczby całkowitej w systemie ujemnym obliczamy ze wzoru: X = Porównanie wartości U1 z U2:
W ogólności reguła uzupełniania polega na negowaniu bitów liczby i dodaniu 1 do otrzymanego kodu. np. więc 5. Typ stałoprzecinkowy Typ stałoprzecinkowy odpowiada pozycyjnej (uzupełnieniowej) reprezentacji liczby. W tym typie jednak możliwe jest określenie pozycji przecinka. Warto przypomnied, że waga pozycji jest całkowitą potęgą podstawy β. W momencie, gdy ustalona liczba pozycji ułamka wynosi r,wartośd każdej liczby podana jest z dokładnością. Można ją przedstawid jako iloczyn liczby całkowitej. Wówczas liczbę taką reprezentuje sekwencja: { } i mnożnika. Reprezentacje stałoprzecinkowe można więc zapisad jako skalowalne reprezentacje liczb całkowitych. Nie ma potrzeby ich osobnej obsługi sprzętowej mogą byd realizowane na tej samej jednostce ALU. 6. Typ zmiennoprzecinkowy Standardem reprezentacji liczb jest użycie notacji inżynierskiej lub naukowej, czyli iloczynu mnożnika i potęgi liczby 10. Można wówczas otrzymad przybliżone wartości rzeczywiste. Realizacja tego sposobu to liczba zmiennoprzecinkowa. Jest ona reprezentowana przez trójkę: (β, M, E), gdzie β podstawa M mnożnik (dawniej Mantysa) E wykładnik (exponent) F = M Jeśli zakres mnożnika nie będzie ograniczony, to liczba zmiennoprzecinkowa może mied różne reprezentacje: F = M, i = -m,, -1,0,1,,m m liczba pozycji mnożnika w ustalonej bazie całkowitej β >= 2. Problem wynikający z powyższych wzorów: Wieloznacznośd. Nie da się jej rozwiązad poprzez ograniczenie bezwzględnej wartości mnożnika od góry. Gdy M <, to zgodnie z powyższymi wzorami ich wyniki są różnymi dozwolonymi reprezentacjami tej samej
liczby. Powoduje to, że prawie 1/β przestrzeni kodowej jest zajęta przez alternatywne reprezentacje tej samej liczby. Prezentacja tego problemu jest pokazana na poniższym obrazku: Podobnie jest przy ograniczaniu rozmiaru mnożnika. Możliwe jest różne kodowanie liczb, których najniższe pozycje są zerami. Aby móc jednoznacznie określid liczbę zmiennoprzecinkową, należy znormalizowad jej mnożnik. Robi się to poprzez ograniczenie wartości bezwzględnej przez kolejne całkowite potęgi podstawy: Każde przeskalowanie takiego mnożnika powoduje jego ponowną denormalizację. Aby zapewnid reprezentację zera albo liczb bardzo małych możliwe są odstępstwa od tej reguły. Należy wówczas dopuścid możliwośd wystąpienia części kodów kodujących dane liczby. Dodatkowo częśd przestrzeni musi zostad również zarezerwowana dla wartości specjalnych, takich jak nieskooczoności. Warto pamiętad, że dokładnośd reprezentacji mnożnika jest stała, co uzależnia gęstośd liczb od wartości mnożnika. W następstwie tego liczby rzeczywiste są w większości tylko przybliżonymi wartościami. 7. Standard IEEE 754 Standardty IEEE 754 i 854 wymagają, aby liczby (oprócz liczb bliskich 0) były znormalizowane. Sam IEEE 754 wymaga,aby mnożnik był z zakresu 1 <= M < 2. Dzięki temu możliwe jest ukrycie najwyższego bitu i wykorzystanie go w inny sposób. Dzieje się tak, ponieważ liczby tak znormalizowane wyglądają następująco: 1,bbbb.bbb. Pierwszym bitem jest bit znaku S (sign). Jeśli liczba zapisana w kodzie dziesiętnym jest ujemna, oznacza to, iż S przyjmie wartośd 1. Jeśli liczba dziesiętna jest dodatnia zero. Dalej następuje 8 bitów kodujących wykładnik 2 (cecha), przy czym kodowanie cechy jest kodowaniem z nadmiarem (BIAS, w tym przypadku BIAS=127) co daje zakres wykładników <-127,128>. Kolejne 23 bity to mantysa liczby, przy czym pomija się wiodący, niezerowy bit. Wartośd liczby znormalizowanej to: F = s znak liczby f wartośd ułamkowa mnożnika 1 + f wartośd mnożnika (mantysa) E wartośd wykładnika w kodzie +N ( )
F nigdy nie będzie równe 0. Dlatego przyjęto, że kod zera zawiera oprócz bitu znaku tylko bity zerowe. Rozróżniane jest zatem zero dodatnie oraz ujemne. Nieskooczonośd +/- - ustawione wszystkie bity wykładnika, mantysa równa 0, może się pojawid np. jako wynik dzielenia przez 0 Poniżej znajduje się zestaw znaków specjalnych, jakie można uzyskad w standardzie: Wyjątki, jakie można otrzymad : - Invalid operation - Division by Zero (dzielenie przez zero) - Overflow (nadmiar wykładniczy liczba zbyt duża) - Underflow (niedomiar, utrata precyzji przy liczbach bliskich 0) - Inexact (niedokładnośd podczas operacji zaokrąglania)