METODY REPREZENTOWANIA IFORMACJI Spis treści METODY REPREZENTOWANIA IFORMACJI System pozycyjny. Zamiana liczby binarnej na dziesiętną (5.1.1; 5.1.2) Otrzymywanie binarnego rozwinięcia liczby dziesiętnej (5.1.3) Długość rozwinięcia binarnego liczby (5.1.4) Szybkie potęgowanie (5.1.5) Reprezentacja binarna liczb ujemnych (5.1.6) Reprezentacja binarna liczb niecałkowitych (5.1.7) 1 2 3 4 5 6
System pozycyjny To taki sposób reprezentowania liczby, w którym wartość liczby zależy od pozycji cyfry w ciągu cyfr
Ciąg bitów Nazywamy binarnym rozwinięciem liczby Najbardziej znaczący bit stoi z lewej strony a najmniej z prawej strony rozwinięcia
Zamiana liczby binarnej na dziesiętną Może być wykonana przy pomocy schematu Hornera, bo
Zamiana liczby binarnej na dziesiętną- przykładowy kod programu function TForm1.BinarnaNaDZiesietna(const Value:String):string; var i, //licznik kroków n, //długość ciągu a :integer; begin if Length(Value)<1 then exit; n:=Length(Value); i:=1; a:=0; //a:=(...(b(n)+b(n-1))*2+...)*2+b(0) while i<n do begin a:=(a+StrToInt(Value[i]))*2; i:=i+1; end; a:=a+StrToInt(Value[i]);//dodaj ostatni wyraz bez mnozenia przez 2 result:='Wynik: '+IntToStr(a);
Zamiana liczby dziesiętnej na binarną ALGORYTM: Zamiana dziesiętnej liczby naturalnej na postać binarną. Dane: Dziesiętna liczba naturalna a. Wynik: Ciąg bitów, tworzących binarne rozwinięcie liczby a KROK 1: Powtarzaj KROK 2, dopóki a jest liczbą większą od Zera, w przeciwnym razie wykonaj KROK 3 KROK 2: Za kolejny bit rozwinięcia przyjmij: s[i]:=a mod 2 i przypisz a:=a div 2 KROK3 Podaj wynik czytając od końca tablicę bitów s[i] SCHEMAT
Schemat algorytmu zamiany liczby dziesiętnej na binarną KOD FUNKCJI
Kod funkcji algorytmu zamiany l. 10 na l. 2 function TForm1._10na2(const Value:string):string; var a,i:LongInt; s:string;//łancuch wyniku-kolejne ZERA lub JEDYNKI begin if Value=''then exit;//wyskocz jesli podano puste dane a:=StrToInt(Value); //zamien łancuch znaków na liczbę całkowitą while a>0 do begin s:=s+ IntToStr(a mod 2);//zapamietaj resztę z dzielenia a:=a div 2; //zapamietaj część calkowitą z dzielenia end; //czytaj wynik od końca for i:=length(s)downto 1 do result:=result+s[i];
Jak wyznaczyć długość rozwinięcia binarnego liczby?
Algorytm szybkiego potęgowania. Stosując binarne rozwiniecie wykładnika potęgi można bardzo znacznie przyśpieszyć obliczenie potęgi o dowolnym wyznaczniku. Przykładowo x^9=x*x*x*x*x*x*x*x*x jest równoznaczne z wykonaniem 8 mnożeń Ale x^2 mnożenie 1, czyli x*x=x^2 (x^2)*(x^2) mnożenie 2 (x^4)*(x^4) mnożenie 3 x^8*x mnożenie 4, cztery tak wykonane mnożenia to x^9 Liczbę 9 w tym wypadku nasz wykładnik można przedstawić tak: 9=(1001)2 Biorąc to pod uwagę można podać taki przepis na obliczenie potęgi (znany w Indiach od 200 roku p.n.e)
Algorytm szybkiego potęgowania „od lewej do prawej.” 9=(1001)2 najbardziej znaczący bit w rozwinięciu wykładnika odpowiada rozpoczęciu obliczeń od przyjęcia liczby za początkową wartość potęgi każda następna pozycja w rozwinięciu odpowiada podniesieniu częściowego wyniku do kwadratu i ewentualnie pomnożenie przez x, jeśli bit rozwinięcia na tej pozycji jest równy 1 Przyjmując oznaczenia: P- potęgowanie, X - mnożenie to w miejsce każdej JEDYNKI za wyjątkiem bitu najstarszego wstawiamy symbol PX (potęguj i mnóż), zaś za każdy bit ZEROWY wstawiamy symbol P (potęguj) otrzymamy taki zapis 1001 >symbolicznie> PPPX, ten zapis odpowiada wykonaniu 4 mnożeń Realizując potęgowanie w kodzie programu można jego budowę usprawnić wykorzystując fakt, że zamiana liczby dziesiętnej na jej rozwinięcie binarne odbywa się od bitu najmniej znaczącego - od końca. Czyli od PRAWEJ DO LEWEJ
Algorytm szybkiego potęgowania „od prawej do lewej” Dane: Podstawa potęgi - liczba x, wykładnik potęgi - liczba n Wynik: Wartość potęgi w:=x^n Krok 1 Przyjmij wynik W:=1 Krok 2 Jeśli kolejny bit liczony od prawej strony rozwinięcia binarnego wykładnika potęgi wynosi 1, to zwiększ wynik X razy; Czyli Jeśli n mod 2 = 1 to w:=w*x Krok 3 Dopóki n>0 przypisz n:=n div 2; jeśli n=0 to zakończ algorytm Krok 4 Wykonaj potęgowanie x:=x*x; Wróć do kroku 2 SCHEMAT BLOKOWY
Schemat blokowy- „od prawej do lewej” Postać funkcji
Ciało funkcji- „od prawej do lewej” function TForm1.Potega(x,n:extended):string; var w:extended;//wynik begin w:=1; //funkcja Round() wprowadzam ponieważ zmienne x, n nie są typu całkowitego //zastosowanie typu EXTENDED pozwala wykonywać działania na dużych liczbach while n>0 do begin if Round(n) mod 2 =1 then w:=w*x; n:=Round(n) div 2; x:=x*x; end; result:=Format('%g',[w]);
Reprezentacja binarna liczb całkowitych ujemnych W zapisie cyfrowym nie przewiduje się znaku minus. Stąd liczby ujemne są odpowiednio kodowane. Przewiduje się dla znaku liczby dodatkowy bit według poniższej umowy: liczba dodatnia poprzedzona jest bitem 0 (zero) liczba ujemna poprzedzona jest bitem 1 (jeden) Przykładowo w języku programowania PASCAL można rozróżnić typy liczb całkowitych (wybrane)
Kodowanie znaku liczby- reprezentacja uzupełnieniowa Liczba ujemna jest liczbą przeciwną do dodatniej. Suma pary takich liczb zawsze daje zero. Na przykład 5+(-5)=0 ale 00000101 + 10000101 da 00000101 +10000101 ----------------- 10001010 czyli minus 10 z uwzględnieniem bitu znaku (bez to 138) Aby można było prawidłowo wykonywać działania matematyczne z uwzględnieniem znaku liczb stosuje się tak zwaną reprezentację uzupełnieniową, która reprezentację binarną liczby całkowitej traktuje jak poniżej: gdy a >= 0 reprezentacja binarna liczby a nie ulega zmianie gdy a<0, to reprezentacja binarna liczby a odpowiada reprezentacji binarnej liczby wyznaczonej z zależności 2^n+a, gdzie n to liczba bitów przechowujących daną liczbę wraz z jej znakiem. W tym przypadku: 2^8+(-5)=256-5=251 czyli 11111011 SPRAWDZENIE + 11111011 ------------------ (1)00000000 Czyli: Suma liczby i jej liczby przeciwnej wynosi ZERO
Algorytm: Przedstawienie liczby ujemnej w reprezentacji uzupełnieniowej Dane: Binarne rozwinięcie liczby naturalnej wraz z bitem znaku równym ZERO Wynik: Binarne rozwinięcie liczby przeciwnej -(minus)a wraz z bitem znaku w reprezentacji uzupełnieniowej Krok: Przesuwaj się od prawej do lewej, czyli w kierunku od najmniej znaczącego bitu, pozostawiaj bez zmian wszystkie początkowe bity równe zero i pierwszy bit równy 1, a każdy następny bit zmień na przeciwny, czyli 0 na 1, a 1 na 0 SCHEMAT BLOKOWY
Schemat blokowy alg. reprezentacji uzupełnieniowej
Ciało funkcji- reprezentacja uzupełnieniowa function TForm1.RepUzupelnieniowa(Value:string):string; var fZmien:boolean;//flaga zmiany bitow i:integer; a:int64; begin fZmien:=false; if Value=''then exit;//wyskocz jesli podano puste dane i:=Length(Value); while i>0 do begin if fZmien then begin if Value[i]='1' then Value[i]:='0' else Value[i]:='1'; end else if (VAlue[i]='1')then fZmien:=true; i:=i-1; end; result:=Value;
Reprezentacja binarna liczb niecałkowitych Binarna reprezentacja liczb niecałkowitych w systemie pozycyjnym o podstawie p jest zapisana jak poniżej: W przypadku zapisu binarnego należy odpowiedni zakodować znak liczby oraz znak dziesiętny. Znak liczby koduje się pierwszym bitem (według poznanych zasad) zaś znak dziesiętny pamiętany jest dzięki umowie dotyczącej liczby bitów przypadających na część całkowitą liczby wraz ze znakiem (plus minus) oraz liczby bitów części dziesiętnej. Przykładowo: n=8 bitów (część całkowita z bitem znaku) m=8 bitów(część dziesiętna) 7 6 5 4 3 2 1 0 | -1-2-3-4-5-6-7-8 12.625 to 00001100 10100000 2^3+2^2+2^(-1)+2^(-3)
Algorytm reprezentacji binarnej części dziesiętnej liczby SCHEMAT BLOKOWY
Algorytm reprezentacji binarnej części dziesiętnej liczby- schemat blokowy Ciało funkcji
Algorytm reprezentacji binarnej części dziesiętnej liczby-ciało funkcji function TForm1.RozwiniecieUlamka(const Ulamek:string; const nBitow:string):string; var a:extended; i, //licznik krokow d, //dzielnik, kolejna potega liczby dwa n:integer;//dlugosc zapisu w bitach, ma sens dokładnosci begin result:='';//pusty łancuch wyniku dzialania funkcji if (Ulamek='')or(nBitow='')then exit; n:=StrToInt(nBitow);//odczytaj na ilu bitach masz pamietac czesc dziesietna if n>16 then exit; a:=StrToFloat('0,'+Ulamek); i:=0; d:=2; while i<n do begin if a>=1/d then begin result:=result+'1'; a:=a-1/d; end else result:=result+'0'; d:=d*2; inc(i); end;