Autor | Zpráva | ||
---|---|---|---|
Anonymní Profil * |
#1 · Zasláno: 28. 2. 2006, 14:54:22
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 |
#2 · Zasláno: 28. 2. 2006, 15:12:59
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 * |
#3 · Zasláno: 28. 2. 2006, 15:16:43
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?
|
||
Časová prodleva: 15 dní
|
|||
zivan Profil |
#4 · Zasláno: 15. 3. 2006, 18:01:45
Ano, proto cyklus s nerovnosti neskonci.
|
||
koudi Profil |
#5 · Zasláno: 15. 3. 2006, 18:06:40
Tohle nějak souvisí s tim, že tu informaci prostě neni možné hardwarově nějak uchovat.
|
||
WanTo Profil |
#6 · Zasláno: 15. 3. 2006, 18:19:25
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 |
#7 · Zasláno: 15. 3. 2006, 18:19:30
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 * |
#8 · Zasláno: 15. 3. 2006, 20:34:10
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 * |
#9 · Zasláno: 15. 3. 2006, 23:16:24
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 |
#10 · Zasláno: 16. 3. 2006, 10:54:03 · Upravil/a: zivan
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. |
||
Časová prodleva: 8 dní
|
|||
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. |
||
Časová prodleva: 8 měsíců
|
|||
zivan Profil |
#12 · Zasláno: 21. 11. 2006, 15:45:39
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. |
||
Časová prodleva: 17 let
|
Toto téma je uzamčeno. Odpověď nelze zaslat.
0