Autor Zpráva
Anonymní
Profil *
Ahoj, programátoři!

prosím, je tohle nekonečný cyklus a jestli ano, tak proč:

$x = 1.0;
$pocet = 0;

while($x != 0.01){
$x -= 0.01;
$pocet++;
}

echo "počet průchodů: $pocet";

Vím, že to nefunguje, a že když jsem to změnil na ($x >= 0.01), tak to
fungovalo, ale nevím proč...
roberta
Profil
teoreticky je to nekonečný cyklus, prakticky nie.
treba si uvedomiť, že ani strojová nula nemá hodnotu presne 0, ale niečo okolo nuly... 0.0000000001 može byť kľudne strojová nula (počet cifier za desatinnou ciarkou závisí od HW/SW). Tento problém sa vyskytuje hlavne pri práci s desatinnými číslami a rieši sa to tak, že sa neporovnáva konkrétna hodnota, ale interval (tak ako si to vyriešil ty)
Anonymní
Profil *
znamená to, že když odečku od 1.0 (což není přesně 1.0) devadesátdevětkrát 0.01 (což není přesně 0.01), tak nikdy se nedostanu na přesnou hodnout $x = 0.01 ... tudíž porovnání selže?
zivan
Profil
Ano, proto cyklus s nerovnosti neskonci.
koudi
Profil
Tohle nějak souvisí s tim, že tu informaci prostě neni možné hardwarově nějak uchovat.
WanTo
Profil
U celých čísel by to nebyl problém.

Jde o to, jak fungují čísla s tzv. pohyblivou desetinnou čárkou. V takovém čísle je uložené samotné číslo a pak měřítko (exponent). Teoreticky by měla desetinná čísla dokázat vyjádřit všechna reálná čísla (z matematického pohledu), ale prakticky to tak nefunguje. Takže se může stát, že z 0.01 počítač udělá třeba 0.009999945991 a porovnání se vyhodnotí jako false.
zivan
Profil
To je otazka?
Je to tim, ze clovek pocita v desitkove soustave a data jsou ulozena ve dvojkove. Realna cisla neni mozne rozumne ulozit s neomezenou presnosti ve dvojkove soustave.
printf-jinde
Profil *
Skoro před měsícem byl tenhle úkol jako inzerce seznamu v jednom časopise. Bylo tam toto:

double x=1.0;
int steps = 0;
while (x != 0.01) {
steps++;
x -= 0.01;
}
printf("Done in %d steps", steps);

Jestli prý tu chybu objevíte, tak hurá do týmu :-)
Kajman_
Profil *
A nezáleží na procesoru? To by mě zajímalo, jak to dopadne na 486, protože počátkem pentia se začaly teprve dělat vtipy, že ty výsledky nejsou dobře, ale zase jsou rychle :-)
zivan
Profil
Zalezi to na typu cisla do ktereho tu hodnotu ukladas.

Novejsi procesory (16b -> 32b - 64b) umeji rychleji pracovat s presnejsimy cisly. I 286 muze pocitat s hodne presnymi cisly...jen to bude podstatne dyl trvat.

Nejak jsem pres google nenasel na tohle zakladni tema zadny clanek. Nechcete to nekdo sepsat? :-)

Edit: Jo a ty chyby v Pentiu byly jen v prvnich verzich na 60 a 90MHz.
zivan
Profil
Sepsal jsem neco jako první verzi clanku o tomhle tematu - http://zivan.php5.cz/www_code/problem_realnych_cisel.php
Muzete na to mrknout a pripadne napsat pripominky po kliknuti na prezdivku pod menu. Snad je to srozumitelne, skola i programovani na me urcite zanechaly stopy, tak mi to pripada dost lehke na pochopeni.
zivan
Profil
Upravil jsem si stranky a zmenila se adresa clanku o realnych cislech na http://zivan.php5.cz/vyvoj/problem_realnych_cisel.php

Nejaky moderator muze zmenit predchozi odkaz a tento smazat. Ja ho po editaci moderatora nemuzu menit.
Toto téma je uzamčeno. Odpověď nelze zaslat.