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)