Autor Zpráva
Alice
Profil *
Konečně jsem dala dohromady formulář na vstah celkového tlaku ve vodě a hloubky. Formulář počítá, ale při nějakých hodnotách blbosti. Pomozte mi prosím odstranit chybu. např: do pole phloubka zadám hodnotu 20 a v poli ptlak to ukáže hodnotu 0.30000000000000004 . Kde se tam bere ta 4? netušim. Ten samý problém se mi stane, když do pole ptlak vložím hodnotu 0.4 to to zas ukáže v poli phloubka hodnotu 30.000000000000003 .
<form name="aaa">

<input type="text" size="33" name="phloubka" value="0" onchange="vhloubka()">
<input type="text" size="33" name="ptlak" value="0" onchange="vtlak()">
<button onclick="">Vypočítat</button> <input type="reset" value="Vynulovat">
</form>

<script>
function vhloubka(){

var c,p,f,y, text;
y = document.getElementById("phloubka").value;
p = y * 0.01;
c = p + 0.1;
text = c;
f = window.document.aaa.ptlak;
f.value = text;

}

function vtlak(){

var s,p,f,y, text;
y = document.getElementById("ptlak").value;
p = y - 0.1;
s = p * 100;
text = s;
f = window.document.aaa.phloubka;
f.value = text;

}

</script>
Hooonza
Profil *
Jestli to hází vždycky takovouto chybu, zkusil bych výsledek zaokrouhlit a ve výpisu pak omezit počet desetinných míst. (třeba na 2 desetinná místa:
a = (Math.round (a * 100)) / 100;
)

H.
Hooonza
Profil *
<form name="aaa">

<input type="text" size="33" name="phloubka" value="0" onchange="vhloubka()">

<input type="text" size="33" name="ptlak" value="0" onchange="vtlak()">

Vypočítat <input type="reset" value="Vynulovat">

</form>
<script>

function vhloubka(){
var c,p,f,y, text;

y = document.aaa.phloubka.value;

p = y * 0.01;

c = p + 0.1;

c = (Math.round (c * 100)) / 100;

text = c;

f = window.document.aaa.ptlak;

f.value = text;
}
function vtlak(){
var s,p,f,y, text;

y = document.aaa.ptlak.value;

p = y - 0.1;

s = p * 100;

s = (Math.round (s * 100)) / 100;

text = s;

f = window.document.aaa.phloubka;

f.value = text;
}


</script>
Alice
Profil *
Jo,tohle mě taky napadlo, ale je to blbost.
1) složitější kód
2) vyřeším s tím pouze tenhle případ...pro další výpočty nepřesné
....
Přece to nepočítá takhle blbě normálně!
Věřím že je chyba u mě.
Screamer
Profil *
Alice: ne neni, uvedom si ze CPU pocita v binarnim kodu, plno cisel ktere ale prevede do binarky je periodicke (nebo aspon nekonecne), vsechno se proto zaokrohouje a pri zpetnem prevodu vznikaji tyhle zbytky, jediny reseni je zaokrouhlit na mene des. mist
Screamer
Profil *
pardon ne kod ale soustava
peta
Profil *
Alice
Ano, viz Screamer, JS neni pripraven na pocitani s velikymi cisly.
Nicmene si muzes napsat vlastni objekt MATH1, ketery uz s nimi bude umet pracovat.
Neco jineho je treba delhi, ktere umi zpracovavat i 32 cislic a mozna vic.
Nemuzu to ted najit, malokde se to uvadi, jak velke ciselne typy JS pouziva...

Nasel jsem, ze pouziva (javascript-reference.info):
Number.MIN_VALUE = 1e-307 (ale s tim neumi pracovat Opera)
Number.MAX_VALUE = 1e+308
pro operace SHIFT (5>>3) pouziva 32-bit
pro cisla pouziva 64-bit floating.point (2^64=18446744073709551616, coz je 20 cislic, +- nejake cislo na znamenko a neco malo pro E, takze takovych 17 by to mohlo byt)
Jenze MATH muze pracovat mozna s mene cislicemi, je tam cosi uvadene 15, ale to se mi uz nechce prekladat.
peta
Profil *
Mimochodem, jestli je tam tato chyba, ja bych zkusil prevod string na cislo, nejlepe ne E-tvar.
Nebo
y = document.aaa.phloubka.value;
p = y * 0.01;
c = p + 0.1;

y = document.aaa.phloubka.value;
p = (y*1) * 0.01;
c = p + 0.1;

Je mozne, ze vynasobenim 0.01 dojde k nejake chybce pri pocitani. Chtelo by to mozna uvest www prohlizec, ktery pouzivas. Jsem teda ten priklad nezkousel, protoze by mel fungovat dobre, ale mozne je vsechno, zvlast u Opery.
peta
Profil *
Ve FF mi to dela taky, sranda. Zadam 20 to prvni kolonky a vypise to velike cislo :)
<form name="aaa">
<input type="text" size="33" name="phloubka" value="0" onchange="vhloubka(this)">
<input type="text" size="33" name="ptlak" value="0" onchange="vtlak(this)">
<button onclick="">Vypočítat</button> <input type="reset" value="Vynulovat">
</form>

<script>
function vhloubka(y)
{
var f,p,c, text;
f = window.document.aaa;
y = y.value;
p = y * 0.01;
c = p + 0.1;
text = c;
f.ptlak.value = c;
}

function vtlak(y)
{
var f,p,s, text;
f = window.document.aaa;
y = y.value;
p = y - 0.1;
s = p * 100;
f.phloubka.value = s;
}
</script>

Poznamka:
vhloubka(this)
vhloubka(y)
y = y.value;
je totez jako
f = window.document.aaa;
y = y.phloubka.value;

Nevim, proc motas ID s NAME v jednom scriptu, kdyz to nema vyznam...
Joker
Profil
Screamer, peta:
Zajímavé výklady toho proč tenhle efekt nastává, ale není to úplně přesné. Ve skutečnosti to s velkými čísly nesouvisí, ani tak moc s počítáním ve dvojkové soustavě.

Ve skutečnosti je toto způsobené samotným principem ukládání čísel v paměti počítače (resp. jakéhokoliv elektronického zařízení). Problém uvidíte snadno, pokud si dáte dohromady fakta:
Pokud vezmete libovolná dvě různá reálná čísla, leží v intervalu mezi nimi nekonečný počet reálných čísel. Jelikož do paměti uložíte jen konečný počet různých hodnot, logicky není možné uložit všechna reálná čísla z nějakého intervalu.
Takže ve skutečnosti lze do paměti uložit jenom některé hodnoty v tom intervalu a neuložitelné hodnoty se zaokrouhlují na nejbližší uložitelnou hodnotu. To má ale za následek právě tu nepřesnost ve výpočtu.
S reálnými čísly v počítači nemusí například platit ani že 1+1=2. Například kapesní kalkulačky tenhle problém řeší tak, že "uvnitř" počítají s vyšší přesností než ukazují na displeji a výsledky pak zaokrouhlují. Programovací jazyky v počítači tohle nechávají na programátorovi.

Osobně bych to dělal stejně jako ty kalkulačky a výpočty zaokrouhloval na vhodný počet desetinných míst.

Poznámka:
S tímhle chováním u reálných čísel v počítačích je potřeba počítat obecně. Například tento cyklus:
skoncit = false;
i = -1.5;
while(!skoncit){
i = i + 0.5
if(i==0) skoncit = true;
}

nemusí nikdy skončit.
Ještě dodám, že s podobným problémem se můžete setkat obecně, třeba i při výpočtech například v Excelu.
Toto téma je uzamčeno. Odpověď nelze zaslat.

0