Další celočíselné typy Současné implementace Pascalu obsahují kromě typu integer ještě další celočíselné typy. Při náročnějším počítání v Turbo Pascalu oceníme typ longint; do proměnných tohoto typu můžeme uložit hodnoty v rozsahu od -2 147 483 648 do 2 147 483 647 (má tedy stejný rozsah jako typ integer v Lazarusu a v Delphi). Pro některé speciální výpočty se může hodit typ word, který „nemá znaménko“ – nemůže obsahovat záporná čísla. Rozsah jeho hodnot je od 0 do 65 535. V Lazarusu a v Delphi je k dispozici také bezznaménkový typ longword, který může obsahovat čísla v rozsahu od 0 do 4 294 967 295. S hodnotami těchto typů lze provádět všechny operace, o nichž jsme hovořili v souvislosti s typem integer. Jejich použití je však spíše ojedinělé, a proto se jimi v této knížce nebudeme zabývat.
Příklad 7.1 Napíšeme funkci IntNaRetezec, která dostane celé číslo typu integer a vrátí znakový řetězec obsahující zápis tohoto čísla v desítkové soustavě; umístíme ji do jednotky retezce, s níž jsme se setkali v několika předchozích kapitolách. Její hlavička bude mít tento tvar: function IntNaRetezec(daneCislo: integer): string; Nejprve si ujasníme postup. Vytvořit řetězec obsahující zápis zadaného čísla znamená získat postupně jeho jednotlivé znaky – číslice a případné znaménko. Jak uvidíme, je výhodné postupovat od konce, tedy jako první získat číslici vyjadřující jednotky, pak získat číslici vyjadřující desítky atd. Předpokládejme nejprve, že zadané číslo, uložené v parametru daneCislo, je kladné. Snadno zjistíme, že vydělíme-li daneCislo deseti, bude zbytek po dělení právě hodnota odpovídající poslední číslici. Nyní potřebujeme „odtrhnout od zadané hodnoty poslední číslici“, tedy získat číslo, jehož zápis bude končit předposlední číslicí daného čísla. I to je jednoduché: tento požadavek splňuje podíl získaný celočíselným dělením daného čísla deseti, tedy daneCislo div 10. Předposlední číslice daného čísla je poslední číslicí tohoto podílu, a poslední číslici už získat umíme. Podobně získáme třetí číslici od konce atd. Ukažme si to na příkladu: předpokládejme, že daneCislo = 123. Výsledkem operace daneCislo mod 10 je 3, což odpovídá skutečnosti, že poslední číslice je 3. Výsledkem operace daneCislo div 10 je číslo 12; jeho poslední číslice je předposlední číslicí zkoumaného čísla, takže ji získáme jako zbytek po dělení číslem 10 atd. Bude-li dané číslo záporné, získáme uvedeným postupem znakovou reprezentaci jeho absolutní hodnoty a k ní pak připojíme znaménko minus. Bude-li dané číslo rovno 0, vrátíme jako výsledek řetězec obsahující jediný znak '0'. Zbývá vyřešit poslední problém: zatím jsme si ukázali, jak získat celočíselnou hodnotu odpovídající hledané číslici. My ale potřebujeme znak vyjadřující tuto hodnotu. Jak ho získáme? (Výsledkem operace daneCislo mod 10 je hodnota typu integer – např. 3; my ale potřebujeme znak '3'. ) Můžeme postupovat takto: vezmeme-li znakový řetězec const cislice = '0123456789'; platí, že cislice[1] je '0', cislice[2] je '1' atd. Chceme-li tedy číslici vyjadřující hodnotu i, kde 0 ≤ i ≤ 10, vezmeme z řetězce cislice znak s indexem i + 1. Když už umíme najít potřebné znaky, musíme z nich složit řetězec. To uděláme např. tak, že vezmeme prázdný řetězec vyjádřený zápisem '', a budeme k němu získané znaky postupně připojovat.
98 Pascal – programování pro začátečníky
Ukázka elektronické knihy, UID: KOS182821
Tak ovšem získáme řetězec, jenž bude obsahovat potřebné znaky v obráceném pořadí, a proto ho nakonec otočíme. Nyní už můžeme formulovat náš postup jako algoritmus. Ten bude používat dvě pomocné proměnné. První z nich, vysledek, bude typu string a bude obsahovat výsledek naší práce – požadovaný řetězec. Druhá pomocná proměnná, n, bude typu integer a budeme si do ní ukládat hodnoty získané opakovaným dělením daného čísla deseti. 1. Příprava. Do proměnné n ulož absolutní hodnotu parametru daneCislo. Do proměnné vysledek ulož prázdný řetězec, tedy hodnotu ''. 2. Test nuly. Je-li daneCislo = 0, ulož do proměnné vysledek řetězec '0' a jdi na krok 8. 3. Získání znaku. K řetězci vysledek připoj znak cislice[n mod 10 + 1]. 4. Přechod k další číslici. Do proměnné n ulož hodnotu n div 10. 5. Získali jsme všechny číslice? Je-li n > 0, vrať se na krok 3. 6. Připojení znaménka. Je-li daneCislo < 0, připoj k řetězci vysledek znak '-'. 7. Otočení řetězce. Přerovnej znaky v řetězci vysledek v opačném pořadí. 8. Konec. Řetězec vysledek obsahuje znakovou reprezentaci zadaného čísla. Je zřejmé, že kroky 3–5 tvoří cyklus, který se opakuje, dokud nedospějeme postupným dělením čísla n deseti k nule. Podívejme se na zdrojový kód této funkce: {Soubor 07\01\retezce.pas} function IntNaRetezec(daneCislo: integer): string; var vysledek: string; n: integer; const zaklad = 10; begin if daneCislo = 0 then begin IntNaRetezec := '0'; end else begin vysledek := ''; n := abs(daneCislo); while n > 0 do begin vysledek := vysledek + cislice[n mod zaklad + 1]; n := n div zaklad; end; if daneCislo < 0 then begin vysledek := vysledek + '-'; end; IntNaRetezec := OtocRetezec(vysledek); end; end; Abychom se vyhnuli používání magického čísla 10, deklarovali jsme pojmenovanou konstantu zaklad. Jméno vychází ze skutečnosti, že číslo 10 je základem desítkové soustavy. Kdybychom chtěli takto získat reprezentaci daného čísla v jiné soustavě, stačilo by změnit hodnotu základu, tedy této konstanty.
Základní datové typy 99
Ukázka elektronické knihy, UID: KOS182821
Otočení řetězce jsme naprogramovali jako samostatnou funkci. I když jde o velmi jednoduchý podprogram, jeho zdrojový text zde neuvádím, neboť se nijak netýká celých čísel; vrátíme se k němu později v příkladu 7.7. Předtím si ho můžete prohlédnout v souboru 07\01\retezce.pas.
Ve skutečnosti budeme pro převod celých čísel na znakový řetězec používat standardní knihovní proceduru Str. Tato procedura očekává jako první parametr hodnotu číselného typu a jako druhý parametr proměnnou typu řetězec, do které uloží výsledek. Předchozí příklad nám však ukázal, jak takovýto převod vlastně funguje.
7.1.2 Reálná čísla Skutečné výpočty se neobejdou bez zlomků, a tedy bez racionálních čísel. K jejich zobrazení máme v Pascalu několik datových typů; nejčastěji se používá typ real, proto se o těchto číslech v programátorském žargonu hovoří jako o reálných číslech.
Typ real Tento datový typ zabírá v Lazarusu a v Delphi 8 bajtů. Může vyjádřit nulu a nenulová čísla, jejichž absolutní hodnota leží v rozmezí od 5 × 10-324 do 1,7 × 10308. Tato čísla budou mít v desítkové soustavě nejvýše 15–16 platných číslic. V Turbo Pascalu zabírá typ real 6 bajtů a může vyjádřit reálná čísla s absolutní hodnotou v rozmezí od 2,9 × 10-39 do 1,7 × 1038, a to s přesností 11–12 platných číslic v desítkové soustavě. Skutečné rozmezí hodnot uvádím jen pro zajímavost, rozhodně nemá smysl si ho pamatovat. Důležité je vědět, že ne všechna reálná čísla lze v počítači vyjádřit, takže výsledek jakékoli operace bude téměř vždy více nebo méně nepřesný, vznikne zaokrouhlením na nejbližší číslo, které v počítači vyjádřit lze. Poznamenejme, že v Lazarusu a v Delphi lze pro tento datový typ použít také jméno double.
Jak zapisujeme reálné literály Chceme-li v programu zapsat konstantu představující reálné číslo, máme dvě možnosti: ❚ Použijeme zápis podobný jako v běžném životě, pouze desetinnou čárku nahradíme tečkou. Mezi číslicemi opět nesmíme udělat mezeru. To znamená, že napíšeme např. 12345.6789 nebo 0.1234. Tomuto zápisu se říká tvar s pevnou řádovou tečkou. ❚ Použijeme zápis odvozený od tvaru používaného pro velmi veliká nebo velmi malá čísla, jako je 6,29 × 10-29. Přitom desetinnou čárku opět nahradíme tečkou, symbol násobení vynecháme, místo základu 10 napíšeme E nebo e a za ně napíšeme exponent. To znamená, že výše uvedené číslo zapíšeme 6.29E-29; číslo opět nesmí obsahovat žádné mezery. Tomuto zápisu se říká semilogaritmický tvar; uvidíte také vědecký zápis. (Poznamenejme, že před symbolem E může stát reálné číslo ve tvaru s pevnou řádovou čárkou nebo celé číslo; lze napsat i 1E4, což znamená 104.) Tímto způsobem zapíšeme reálné číslo i v případě, že ho zadáváme jako vstup z klávesnice čtený procedurou read nebo readln.
Operace s reálnými čísly Při aritmetických operacích s reálnými čísly máme k dispozici stejné operátory jako při práci s celými čísly, chybí pouze operátory div a mod, neboť celočíselné dělení nemá pro reálná čísla smysl. Přehled operátorů použitelných pro reálná čísla ukazuje následující tabulka.
100 Pascal – programování pro začátečníky
Ukázka elektronické knihy, UID: KOS182821