Práca s reálnymi číslami na počítači
Úvod
Základný rozdiel medzi "matematickými" reálnymi číslami a reprezentáciou reálnych čísel na počítači je to, že v počítači sú
reálne čísla nespojité. Dôsledkom toho je, že len niektoré reálne čísla sú v počítači
zobrazené presne, ostatné sú zobrazené približne - t. j. s nejakou chybou.
Najhustejšie sú reálne čísla okolo nuly a tam teda vzniká pri zápise čísla do počítača najmenšia chyba.
Čím sme ďalej od nuly, tým je chyba väčšia.
Dôsledok:
1. Ku každému reálnemu číslu a existuje reálne číslo b>0 také, že a+b=a.
2. Ku niektorým číslam a<>0 existuje reálne číslo b také, že a/b=0.
3. Ku niektorým číslam a<>0 existuje reálne číslo b<>0 také, že a*b=0.
Príklady
1. Ku číslu 1 nájdi najväčšie reálne číslo b>0 také, že a+b=a.
2. Ku číslu 1 nájdi najmenšie reálne číslo b>0 také, že a/b=0.
3. Ku číslu 1 nájdi najväčšie reálne číslo b>0 také, že a*b=0.
Aritmetické operácie s reálnymi číslami
Pri každej operácii s reálnymi číslami +,-,*,/ sa chyba výsledku môže zväčšiť.
Zo štatistiky je známy fakt, že chyba môže pri rozdiele vzrásť až do katastrofálnych rozmerov.
Vo všeobecnosti pri súčte je chyba tým väčšia, čím sú čísla od seba ďalej, tj ak
sú čísla veľmi rozdielnych veľkostí môže nastať prípad, že väčšie číslo sa súčtom
vôbec nezmení.
Z toho vidieť, že ak ku veľkému číslu pripočítavame "veľa" malých hodnôt výsledok môže byť hodne skreslený.
- Úloha 1:
- Pripočítajte ku číslu 10 000 100 000-krát číslo 0.01 a číslo 10000 potom od
výsledku odoberme. Výsledkom by malo byť 1 000. Počítač však vráti hodnotu 1000.0000005364.
Treba si uvedomiť, že pri jednom pričítaní nám výsledok vypíše presne ale pri opakovaní pričítania sa
chyba hromadí až sa to prejaví na výpise (to ale neznamena ze ak porovnáme hodnoty 10 000+0.01 a 10 000.01, že budú
rovnaké).
Ak chceme zistiť akej chyby sa počítač pri súčte 10 000 a 0.01 dopustil postupujme nasledovne:
a:=10000;
b:=0.01;
c:=a+b;
d:=c-a;
d:=c-b;
a teraz v premennej d je odhad chyby, ktorej sme sa dopustili.
Tí ktorí tipovali, že v d musí byť 0 budú prekvapení. Bude tam asi 5.36E-9.
Úloha na cvičenie:
Využite to, že vieme určiť chybu, ktorú spravíme pro každom sčítaní a upravte program v úlohe 1
tak, aby súčet bol presne.
Návod: sčitujte do pom. premennej vzniklé chyby a po cykle "opravte" výsledok o zistený
súčet chýb. Výsledok by mal byť už presne.
Testovanie reálnych čísel
Už som niečo naznačil v predošlom príklade.
Napr.
if 0.6+0.1=0.7 then ... else ... sa zhodou okolností vykoná vetva else
if 0.2+0.1=0.3 then ... else ... sa zhodou okolností vykoná vetva then
pri teste reálnych čísel na rovnosť nastáva vlastne náhodná udalosť a nedá sa rozhodnúť, ktorá vetva
programu sa vlastne vykoná.
Majme program
Var x:real;
Begin
x:=0;
while x < 1 do
Begin
podpr;
x:=x+0.1;
End;
End.
Tu je test na rovnosť nahradený testom na menší ale neurčitosť sa tým neodstránila. Nedá sa
určiť koľko krát sa podr vykoná. "Oprava" by spočívala v nahradení čísla 1 číslom
1.01 ak chceme podpr volať 11-krát alebo číslom 0.99 ak chceme podpr volať 10-krát.
Úloha:
Napíšte program, ktorý bude tabelovať funkciu
f(x)=sin(x)/x ...pre x nenulové
f(x)=1 ...pre x nulové
v intervale <-1;1> s krokom d
Pozn. Treba len vyriešiť ako sa opýtať, či je x=0