[ Predrag Damnjanovic @ 04.03.2002. 18:31 ] @
float a;
a=2.001;
printf("%f\n", a);
if (a==2.001) printf("Tacno");
if (a==2.001000) printf("Tacno");

Ovo nikad nece ispisati Tacno.
Zasto???
[ Dragi Tata @ 04.03.2002. 19:02 ] @
Hehe, vidi se da nikad nisi programirao u Fortranu :)

Pravilo je da nikad ne koristiš operator == sa float i double, već isključivo sa celobrojnim tipovima.

Promeni test u
if (a-2.001 < EPS || 2.001-a <EPS) printf("Tacno");

gde je EPS jako mali broj, i onda će da radi.

Naravno, možeš i da koristiš fukciju abs
if (abs(a-2.001) < EPS) printf("Tacno");

Inače, na mom kompajleru (VC 6.0) će da radi i ako promeniš float u double, ali generalna konstatacija ipak ostaje: operator == je pouzdan samo sa celobrojnim tipovima. Naravno, u C++u možeš i da napišeš svoju verziju == koja će uvek da radi dobro i sa brojevima u pokretnom zarezu.
[ Dejan Lozanovic @ 05.03.2002. 12:44 ] @
Citat:
zastita:
float a;

a=2.001;

printf("%f\n", a);

if (a==2.001) printf("Tacno");

if (a==2.001000) printf("Tacno");



Ovo nikad nece ispisati Tacno.

Zasto???

Huh tu postoje dva razloga u globalu zasto je to tako, tj zasto mora da se primenjuje metod koji je opisao dragi tata, tj da je abs(a-b)<epsilon. Prvi je vezan za numericku matematiku tj numericka matematika se bavi pojavom gresaka i racanunja sa "priblizno" tacnim brojevima. Gde se pojava gresaka pojavljuje svuda (pri sabiranju oduzimanju mnozenju, deljenje itd...)

A drugi razlog je predstavljanje brojeva u samom racunaru, primera radi ako bi zeleo da broj 0.4 predstavis u binarnom obliku video bi da ti treba beskonacno mnogo cifara, ista stvar kao npr 1/3 da se predstavi u decimalnom obliku :)), e tu onda u pomoc dolaze "kodovi"(8421, visak 3 , itd...) koji konvertuju broj u pogodan binarni oblik da ne bi dolazilo do onakvih primera kao sto je broj 0.4 itd, e sada prilikom tih konvertovanja opet moze da se pojavi neka mala greskica i zato nisi dobio kao rezultat tacno.
[ filmil @ 05.03.2002. 13:14 ] @
Citat:
zastita:
float a;
a=2.001;
printf("%f\n", a);
if (a==2.001) printf("Tacno");
if (a==2.001000) printf("Tacno");

Ovo nikad nece ispisati Tacno.
Zasto???


Dragi cale je napisao kako se problem zaobilazi u programima, a evo i objasnjenja zasto nastaje ovako nesto.

Floating point brojevi predstavljaju se u formatu koji sve vrednosti izrazava kao neki stepen dvojke. Kod tipa float je taj stepen negativan, tj. svi brojevi se iskazuju preko sume nekih od razlomaka 1/2, 1/4, 1/8, 1/16 itd, pa jos puta eksponent, to je ono e+10 na primer.

Deseti deo (0.1), stoti deo (0.01) itd ne mogu se napisati sa konacno mnogo bita u ovakvoj predstavi, nesto slicno kao sto 1/3 u dekadnom sistemu mozes da predstavis samo sa 0.33333, gde broj trojki ide u beskonacnost. Zato kada upises 2.001, desi se odsecanje na najnizem bitu rezultata i u tvoju float promenljivu se ne upise 2.001 nego nesto drugo, sto predstavlja broj 2.001 odsecen na poslednjem znacajnom bitu, koliko god da to iznosi.

Probaj da ispises vrednost float broja koju dobijas citanjem promenljive pa ces videti sta se desava, osim u slucaju da printf funkcija ne zaokruzuje vrednosti (sto ne bi smela da radi).

poz.

[ tosa @ 05.03.2002. 23:42 ] @
Citat:
zastita:
float a;
a=2.001;
printf("%f\n", a);
if (a==2.001) printf("Tacno");
if (a==2.001000) printf("Tacno");

Ovo nikad nece ispisati Tacno.
Zasto???


Cini mi se da razlog moze biti i ovo:
VC++ brojeve zapisane kao 2.001 tretira kao double (veca preciznost od float-a),
a prilikom konverzije iz float u double (prilikom poredjenja promenljiva se konvertuje u double) verovatno nastaje greska.

Moguce da bi ovo radilo (probaj pa vidi)

float a;
a=2.001;
if (a==2.001f) printf("Tacno"); // dodao sam f kod broja ...

ili ovako (manje elegantno resenje koje radi sigurno zbog
iste reprezentacije u memoriji)

float a, b;
a=2.001;
b=2.001;
if (a==b) printf("Tacno"); // dodao sam f kod broja ...

(ovaj kod izgleda smesno, ali jasna je ideja ...)

tosa