Prečo mi nevychádza to epsilon…

Pri riešení úlohy 1.3 ste si medzi sebou istotne všimli, že dostávate rozličné výsledky. Ako je to možné? Prečo to nevychádza?
Samozrejme, že odpovieme protiotázkou: Ako viete, že Vám to nevychádza?

Jednou z možností ako si overiť správny výsledok, je pozrieť sa do  <float.h>:

FLT_EPSILON = 0.00000011920928955078125000000000 = 1.19209E-007

DBL_EPSILON = 0.00000000000000022204460492503131 = 2.22045E-016

Okrem týchto dvoch výsledkov často zistíte strojové epsilon rovné 1.0842E-019 a niekedy dokonca nezávisí od toho, či je premenná typu float, alebo double. Ktoré z týchto troch čísel je správne? Všetky tri – záleží na tom, čo a ako vlastne počítate.

Ak máte v programe test podobný tomuto:

while ( Sum > 1.0 )
{ Sum = 1.0 + Epsilon;

potom pravdepodobne dostanete niektoré z horeuvedených čísel, podľa toho akého typu sú premenné Sum a Epsilon. Výsledkom je potom strojové epsilon pre daný typ čísla podľa IEEE.

Ale ak máte v programe úspornejšiu konštrukciu, napríklad:

while ( (1 + Epsilon/2) > 1.0)

potom zrejme dostanete to tretie, najmenšie číslo. Je to preto, že v prvom prípade počítač výsledok musel uložiť do premennej typu float, resp. double a až potom ho porovnával s číslom 1. V druhom prípade ale počítač nemusí výsledok nikam ukladať, porovnáva len dva výrazy. To sa dá urobiť v registroch procesora, pričom tam sa používa oveľa viac bitov, aby výsledky boli čo najpresnejšie. Takže v tomto prípade nie je strojové epsilon určené formátom IEEE, ale implementáciou float point aritmetiky v procesore…

Na záver len upozornenie, že strojové epsilon nie je najmenšie číslo v počítači. Veď ľahko overíte, že sú aj menšie čísla, napr. 1.000000e-030. A celkom najmenšie je 2.22507E-308 (DBL_MIN z float.h)

Close Menu