Programujeme v jazyku C# - Diel 13. - MIX zaujímavostí I.

Michal Čižmár  /  16. 02. 2005, 00:00

Začíname novú sériu článkov. Tento raz sa nebudeme zaoberať len jednou témou., ale povyberal som rôzne zaujímavosti, s ktorými ste sa možno nestretli v iných programovacích jazykoch. Napr. pre navnadenie : dátový typ, ktorý pracuje s presnosťou na 28 desatinných miest.

Všimol som si, že minulá séria o cykloch mala menšiu čítanosť. Predpokladám, že to bolo spôsobené tým, že cykly v C# nie sú takmer (až na rozsah platnosti premenných) rozdielne oproti C/C++ alebo iných programovacích jazykov. Dúfam, že sa vám prvý kompletný (a veľmi jednoduchý) program z minulého článku páčil a vyskúšali ste si prinajhoršom aspoň či máte dobre nainštalovaný .Net Framework. :-)

>>Rekurzia aj v C#

Aj keď s rekurziou sa môžete stretnúť aj v iných programovacích jazykov, uvádzam ju pretože je to podľa mňa veľmi zaujímavá vec. Lepšie povedané, je to iný štýl programovania (či myslenia?).

Podstatou rekurzie je, že funkcia vo svojom tele volá znovu samu seba. Keď sa rozhodnete takto niečo naprogramovať musíte si najprv rozmyslieť, kedy vnáranie funkcií prestane (t.j. podmienku) a predpis rekurzie. Najlepšie to uvidíte na príklade:

Príklad 13.1

//--------------------------------------------------------
using System;
 class MainClass
{
        
public static void Main()
        {    
          
Console.WriteLine("Faktorial 5 je : {0}", Faktorial(5));
         }
        
public static double Faktorial(long parameter)
       {
           
if (parameter == 1) return 1;
           
else return parameter * Faktorial(parameter-1);
       }
}
//--------------------------------------------------------
Na stiahnutie: www.inet.sk/download/user/Priklad13.1Rekurzia.zip

Vidíte, že funkcia Faktorial obsahu vo svojom tele znovu volanie funkcie Faktorial a podmienku ukončenie rekurzie . t.j if (parameter==1). Druhou stranou veci je, že sme funkcie ešte nepreberali, takže ak ste nepochopili, nič sa nedeje. :-)

>>Kde sa môžem stretnúť s rekurziou?

Zatiaľ všade kde som čítal o rekurzii bol ako prvý príklad použitia uvedený výpočet faktoriálu. Potom nasleduje prehľadávanie adresárov a zoznamov.

Dobrá rada:
Ak nemusíte použiť rekurziu, tak ju radšej nepoužite. :-) Ak spustíte napr. príklad 1 z tohto článku a spustíte si sledovanie vyťaženia systému ( Task Manager) zistíte, že operačná pamäť „akosi“ ubúda. Je to spôsobené postupným vnáraním funkcií, o ktorom si PC musí viesť záznamy (veľmi jednoducho povedané).

>>Dátový typ decimal

Je to veľmi zaujímavý dátový typ. Základná informáciu je, že je to 128bitový číselný dátový typ. Pozrite si článok o dátových typoch a prepočítajte si aké veľké číslo je možné doň uložiť.
Dostane ale chybný výsledok. Pretože toto číslo má nezvyčajnú vnútornú reprezentáciu .

Číslo s pohyblivou desatinou bodkou je rozdelené na tri políčka. Prvé políčko určuje znamienko, druhé expoment a tretie mantisu.
Napr. 2.8x10^5 (tá strieška je namiesto horného indexu). 2.8 je mantisa a 5 je exponent. Klasicky sa tieto čísla uloženeé v PC podľa predpisu, ktorý dokonca určuje norma IEEE 754.

>>V čom je tá nezvyčajnosť?

Klasické dátové typy ako float a double sú ukladané tak, že základ exponentu je číslo 2. To je zdrojom zaokrúhlovacích chýb. Pretože ak prevádzate reálne desiatové číslo (s desatinou bodkou) do dvojkovej sústavy tak sa môže stať, že obyčajne číslo 0.1 bude v dvojkovom sústave periodické (0,000110011...)

Rozdiel je v tom, že dátový typ decimal má za základ exponentu číslo 10 tak ako sme zvyknutý.

Rozsah : 1.0x10^28 až 7.9x10^28
a to isté pre zápornú oblasť.
Presnosť :
28 desatinných miest!!!!!

Ak vás teória o reprezentácii reálnych dátových typov nezaujala pozrite si príklad.
Príklad 13.2

//--------------------------------------------------------
using
System;
class
MainClass
{      
      
public static void Main(string[] args)
      {
          
double c1 = 0.1111111111111119;
         
decimal c2 = 0.1111111111111119M;
         
decimal c3 = 0.0123214565789541232145678912M;
        
        
Console.WriteLine(" c1= {0}c2= {1}",c1,c2);
         Console.WriteLine(" c3= {0}",c3);
      }
}
//--------------------------------------------------------
Na stiahnutie: www.ient.sk/download/user/Priklad13.2_Decimal.zip

Program vypíše toto:
c1= 0,111111111111112
c2= 0,1111111111111119
c3= 0,0123214565789541232145678912

Vidíte, že v prvom prípade nastane chybné zaokrúhlenie double čísla. Väčšinou to nie je problém, ale asi  si určite viete predstaviť oblasti vedy, kde chyba na 16 desatinnom mieste môže byť obrovská. Dá sa to riešiť softvérovo, ale to nie je prípad decimal (preto je aj rýchlejšie) .

>>Čo bude nabudúce?

Určite tušíte, že budeme pokračovať v sérii článkoch o zaujímavostiach programovacieho jazyka C#. Napr. direktíva #warning, príkaz goto, ale to najzaujímavejšie zatiaľ neprezradím... :-)

>>Predchádzajúce diely:
Programujeme v jazyku C# - Diel 12. - Cykly III.
Programujeme v jazyku C# - Diel 11. - Cykly II.
Programujeme v jazyku C# - Diel 10. - Cykly I.

Viac na : www.inet.sk/Csharp

Ak vám niečo nebolo jasné napíšte do diskusie, tam to nájdem najskôr alebo na e-mail.

MICHAL Čižmár
micitn@orangemail.sk



SEE YOU!

Neprehliadnite: