Autor Zpráva
horakcl
Profil
Zkouším si udělat (pro pocvičení) kalkulačku v Javascriptu.
Postupně zadávám číslice před a nebo za desetinnou tečkou, které se objevují na displaji -
potíž je z tímto příkazem:

c1 = c1 + i * Math.pow(10,ZaCarkou);

v sekvenci:

alert(i * Math.pow(10,ZaCarkou));
c1 = c1 + i * Math.pow(10,ZaCarkou);
alert(c1);
ZaCarkou--;

V momentě, když se snažím zadat když se snažím zadat číslo 87.65 (jen u tohoto, jiná namátokově zvolená čísla byla OK),
tak to zadám až po 87,6. Potom když zadám 5ětku: vypíše se mi prvním alertem 0.05 ovšem tím druhým už
87.649999999999999
Proč se to děje a co s tím ?
Díky za odpověď.

Já vím, že je to skoro stejně, ale vypadá to blbě. Co s tím ?
Dero
Profil
Zjednodušeně řečeno je problém v tom, že některá desetinná čísla je obtížné v paměti binárně vyjádřit. Operace nad některými nestabilními desetinnými čísly mohou vést k zaokrouhlovacím chybám. Řešením je zaokrouhlení na fixní počet desetinných míst.

Více info třeba v diskusi na http://mareklutonsky.blog.zive.cz/2009/02/chyba-v-tabulkach-google-docs-12-82-939999999999/
Joker
Profil
Dero
Zjednodušeně řečeno je problém v tom, že některá desetinná čísla je obtížné v paměti binárně vyjádřit.
Přičemž ta "některá" tvoří drtivou většinu reálných čísel :-)
Ve skutečnosti totiž dnešní programovací jazyky obvykle nedokáží uložit spojité číslo. Ono taky reálných čísel je nekonečně mnoho, takže dost dobře nejdou zakódovat třeba do čtyř bajtů paměti. Takže počítačová "reálná čísla" jsou ve skutečnosti jenom nějaká množina "uložitelných" čísel a výsledek operace se prostě zaokrouhlí na to, které je nejblíž.

Pak ještě existuje druhý problém, dám příklad: 3 * 1/3.
1/3 na desetinné číslo je 0,33333333333333333..., když to vynásobím třemi, vyjde 0,99999999999999999... - ať počítám s přesností na kolik chci desetinných míst, nikdy to nebude 1, vždycky to bude 0, a řada devítek.
Třeba kalkulačky tohle obcházejí tak, že výpočty interně dělají na víc desetinných míst, než zobrazují na displeji, a ta "neviditelná" desetinná místa pak zaokrouhlují. Počítač tohle dělat nemůže, protože ani neví, že ta kupa bitů v paměti reprezentuje číslo.
horakcl
Profil
A jo,
c1 = Math.round(c1 * 10000000000);
c1 = c1 / 10000000000;
pomohlo,
díky,

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: