Systemy liczbowe
Program Konwersja;
Uses Crt;
Var Liczba:LongInt;{Liczba w systemie 10 do konwersji}
s:Byte;
Ciag:String;
C:Char;
Procedure Dane(var Liczba:LongInt; var s:Byte);{procedura wczytujaca dane}
Begin
Write('Podaj liczbe do konwersji: ');Readln(Liczba);
Write('Podaj system : ');Readln(s);
End;
{ /\ Dane /\
|| ||
do tej procedury nie bede sie przyczepiac...przy "dobrych checiach uzytkownika" bedzie ok
ale sprobuj np. podac jakis inny znak nic cyfre... zobaczysz ciekawy
Error 106 .. chodzi o to ze program nie moze przyrownac znaku do zmiennej typu liczbowego...
oczywiscie mozna ten error pominac..
ale to moze przy innej okazji ci wytlumacze zeby wiecej nie mieszac}
Function Konw(Liczba:LongInt;s:Byte):String;
Var RD:Byte;
reszty:String;{ciag pojedynczych znakow- char'ow}
Begin
reszty:=' ';{Na poczatek reszty przypisujemy lancuch pusty}
{bo nie wykonalismy zadnego dzielenia}
{heh...a ja myslalem ze lancuch pusty to => reszty:='';
widzisz to?
reszty=' '; w srodku (miedzy apostofami jest wartosc o ktora sie rozchodzi ;)
tam jest odstep- spacja- wedlug kodu
(tablica znakow- w ktorej kazdy znak ma swoj kod liczbowy, spacja to znak)
ASCII to jest znak numer 32...
czy 32 jest puste? nie wydaje mi sie :) ale po co ja cie mieszam...}
{poczatek petli :) }
Repeat
RD:=Liczba mod s; {zmiennej zp (?? chodzi oczywiscie o "RD" :)
przypisujemy reszte z dzielenia}
Liczba:=Liczba div s;{liczbie przypisujemy nowa wartosc,ktora wynika z dzielenia calkowitego}
{tutaj liczba jest redukowana... jezeli dajmy na to... liczba= 55 w systemie=16 wtedy...
RD=7 (55 mod 16), a 55 div 16 (dzielenie calkowite) daje nam tylko 3 calosci...
(liczba=3 petla sie nie konczy)
teraz 3(tylko tyle juz zostalo) mod 16, RD=3 , a liczba=3 div 16 to jest 0 calosci...
wiec dopisane jest 3 a petla sie konczy.. wynik ? 37 :) }
If RD<10 then reszty:=Chr(48+RD)+reszty
{a wiec co to jest wogole i jak to sie je?
RD juz masz wyzej, pamietaj system liczbowy to "s"
RD jest wiec liczba ktora bedzie nastepna w kolejnosci w naszym ciagu- wyniku dodana z przodu...
na przykladzie:
liczba 10 w systemie szestnastkowym...
Liczba=5 s=16 wiec...
RD:=5 mod 16; "mod" wiec RD bedzie rowne reszcie z dzielenia
wiec RD=5;
!ale!
dla Liczba=18 mod 16 wynik bedzie RD=2 bo 16, to juz jedna calosc...a tu chodzi o reszte (16+2=18 :)
idziemy dalej-> Chr(48) jest odwolanie do wyzej wspomnianej tablicy znakow...ASCII pamietasz?
Chr(48) to inaczej znak w tablicy ASCII o numerze 48... czyli "0"
oczywscie wyglada to z wiekszej perspektywy tak:
kod ASCII 48 = znak "0"
kod ASCII 49 = znak "1"
itd...
kod ASCII 56 = znak "8"
kod ASCII 57 = znak "9"
czyli liczby od 0 do 9 ... wazne jest by RD<10 bo dalej bylyby jakies znaczki typu ":" itp.
a to nie jest liczba w systemie szestnastkowym
wiec jezeli RD czyli wynik dzielenia liczby przez sys liczbowy jest <10 wtedy do ciagu
znakow (wyniku), czyli zmienna "reszty" dopisana jest z przodu liczba odpowiadajaca numerowi RD
dopisana z przodu?
reszty:= (najpierw) Chr(48+RD)+ (dopiero) reszty (czyli w pierwszej petli bedzie to "pusty" ciag pozniej beda
sie tu pojawiac po kolei obliczone liczby- w postaci znakow "0".."9"}
else reszty:=Chr(55+RD)+reszty;
{zakladajac tak jak wczesniej- chr(55) +RD (pamietaj RD>=10 bo gdyby bylo <10 wtedy program zalatwil by sprawe
przy tym warunku wczesniej, a do "else" by sie nie zabieral)
czyli przyjmujemy ze 55+10= 65... to jest znak 'A'}
until Liczba=0;
{koniec petli}
Konw:=reszty;
End;
{no dobra...mam nadzieje ze nic nie pokrecilem i ze zrozumiales jak dziala ten program...
jezeli mamy teraz zamienic liczbe z formatu 16-nastkowego na 10-±tkowy}
Procedure Dane2(var Ciag:String);
Begin
write('Podaj liczbe w systemie 16 do konwersji:');readln(Ciag);
end;
{Wczytujesz ciag znakow bo gdybys chcial wczytac liczbe
to wyskoczyl by blad ze np "FF" to nie jest poprawny format liczby ;)}
Function Konw1610(Ciag:String):LongInt;
Var A,Wynik:LongInt;
C:Char;
F,error:Boolean;
ChrNum,EndS:Byte;
B:Integer;
{Krotka dodatkowa funkcja uzywana do okreslenia kwadratu poziomu lev
przy wiekszej ilosci znakow, nie pytaj dokladnie... wpadlem na nia
w przeblysku inteligencji ;)
Sqr(liczba)=liczba podniesiona do kwadratu}
Function Sqr2(Lev,Num:LongInt):LongInt;
Var A,B:integer;
Begin
For A:=0 to Lev-2 do Num:=Sqr(Num);
Sqr2:=Num;
End;
Begin
{qrde jezcze raz sorx za takie opoznienie..raz wymyslilem ten algorytm, potem zapomnialem
i za nic nie moglem go wymyslec..az znowu wpadlo mi do glowy.. ;)
takie zycie roztargnionego programisty... :\
!!!ALGORYTM!!! dla liczby 2-znakowej
Chr[1]*16 + Chr[2] w 0-16 wartosc
na podstawie tego napisalem reszte}
{tutaj mamy poczatkowe wartosci dla wszystkich zmiennych}
Wynik:=0;ChrNum:=0;A:=0;Error:=False;F:=True;
EndS:=Length(Ciag);{Length(S)=ilosc znakow w ciagu S (wczytanego od uzytkownika)}
if EndS=0 then error:=True;
{jezeli nie ma co zamieniac to blad}
While EndS>0 do
Begin
Val(Ciag[EndS],A,B);
{najpierw przyjmujac ze jest to liczba (S[EndS]= ostatni znak z podanego ciagu)}
if ((Ord(Ciag[EndS])>=65)and(Ord(Ciag[EndS])<=70)) then Val('1'+Chr(Ord(Ciag[EndS])-17),A,B)
{teraz sprawdzamy czy jest w granicach A-F czyli w ASCII 65-70, jezeli
tak to zamieniamy na liczby
np dla "A": 65-17=47 czyli 0 do tego z przodu dodajemy '1' i mamy '10' :)
teraz calosc od razu jest przerobiona na zmienna A
! Val(Znak lub ciag znakow , Zmienna , Wynik);
jezeli w znaku lub ciagu znakow jest cos co nie jest liczba np litera to Wynik
przybierze wartosc kolejnosci tej litery w ciagu znakow (dal znaku zawsze bedzie 1) :)}
else if NOT((Ord(Ciag[EndS])>=48)and(Ord(Ciag[EndS])<=57))then error:=True;
{jezeli nie jest to nic z granic A-F to sprawdzamy czy jest to liczba 0-9 ASCII 48-57
jezeli nie, to mamy nieporzadany znak, czyli blad! przy podawaniu liczby}
if F then {F to skrot od first czyli pierwszy :)
potrzebne jest to by pierwsza liczba ktora zostanie wyciagnieta z ciagu znakow
byla przyrowana tak "bez niczego" do Wyniku :)}
Begin
Wynik:=A;
F:=False;
end else Wynik:=A*sqr2(ChrNum,16)+Wynik;
{to juz sam wynik, funkcje masz powyzej}
Delete(S,EndS,1);
{usuwamy ostatni znak z ciagu (juz przerobiony)}
Inc(ChrNum);
{ktory to juz znak?}
EndS:=Length(S);
End;
if error then write('BĄd zapisu liczby do konwersji!');
{czyzby ktos sie pomylil?}
Konw1610:=Wynik;
End;
Begin{Program glowny}
repeat
clrscr;
writeln('Wybierz Opcje:');
Writeln('1-Program do konwersji liczb w systemie 10 na wybrany system');
Writeln('2-Program do konwersji liczb w systemie 16 na dziesiatkowy:');
writeln('Esc-Koniec');
Repeat C:=Readkey;Until ((C='1')or(C='2')or(C=#27));
if C<>#27 then Repeat
If C='1' then
Begin
Dane(Liczba,s);
Writeln('Wynik= ',Konw(Liczba,s));
End;
If C='2' then
Begin
Dane2(Ciag);
Writeln('Wynik= ',Konw1610(Ciag));
End;
Writeln('Kolejna liczba?(T/N) ');
Until UpCase(ReadKey) <>'T';
Until C=#27;
End.