Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  C++ anomaalia märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
asjameez
Kreisi kasutaja
asjameez

liitunud: 10.12.2006




sõnum 15.08.2010 23:56:34 C++ anomaalia vasta tsitaadiga

Niisiis tükk aega proovinud asjast selgust saada, kuid tulutult. Nagu pealkiri ütleb, siis programm, ei saa aru, kui kaks floati on omavahel võrdsed. Tegelikult saab, aga on teatud juhud, kus ei saa. Sellist jama pole isegi täiesti alguse aegu ette tulnud. Piinlik sellist teemat teha, aga no mis parata, võibolla kellelgi tekib hea idee.


for(x = 0; x < SizeX; x += sx) {
   cout << "x: " << x << "Size: " << SizeX << endl;
   if(x == SizeX) cout << "BUSTED!" << endl;
}


Nagu koodist näha, siis x ei tohi mitte kunagi tulla võrdne SizeX-ga. Aga ometi on juhud, kus ta tuleb.
Kui SizeX >= 8 ning sx == 0.2 , siis tekib anomaalia:
1) x = SizeX = 8 (või suurem)
2) ei väljastata BUSTED!

Need kaks punkti peaksid esinema igaljuhul teineteisega koos.
Kõik teised juhud toimivad. Kõik arvud on floatid.
Kommentaarid: 63 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ohohh
Kreisi kasutaja
Ohohh

liitunud: 13.09.2003




sõnum 16.08.2010 01:06:14 vasta tsitaadiga

Floati korral hoitakse murdosa kahendsüsteemis. Kuid kümnendsüsteemi murdosa ei saa üks-ühele kahendsüsteemi murdosana edasi anda.

Seetõttu kui sa kirjutad x += 0.2, siis reaalselt on see midagi taolist: x += 0.199998745 (<- number on illustreeriva tähendusega)

Nüüd tekibki olukord, kus SizeX = 8.00 kuid x on tegelikult natuke väiksem (7.999...).

Kui cout näitab täpselt number kaheksat, siis see teeb tõenäoliselt mingi ümardamistehte enne väljatrükki.
Kommentaarid: 6 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 6
tagasi üles
vaata kasutaja infot saada privaatsõnum
asjameez
Kreisi kasutaja
asjameez

liitunud: 10.12.2006




sõnum 16.08.2010 03:14:59 vasta tsitaadiga

Lugemist floatide kohta:
http://docs.sun.com/source/806-3568/ncg_goldberg.html

For-tsükkel peaks olema ainult integeridest ning selleks tuleb teha üks lisa arvutus:


float x, SizeX = 8, sx = 0.2;
int i, c = SizeX / sx;
for( i = 0; i < c; i++ ) {
   x = sx * i;
   cout << "x: " << x << "\tSize: " << SizeX << endl;
}
if ( i == c )
   cout << "Hello!" << endl;
Kommentaarid: 63 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 61
tagasi üles
vaata kasutaja infot saada privaatsõnum
Ho Ho
HV Guru
Ho Ho

liitunud: 16.02.2002




sõnum 16.08.2010 13:12:14 vasta tsitaadiga

Üldjuhul võrreldakse ujukoma arve umbes nii:
float f1, f2;
const float epsilon=0.00001;
if (abs(f1-f2)<epsilon) {
   cout<<f1<<" == "<<f2<<endl;
}
Epsiloni väärtus siis anna vastavalt sellele kui suurt täpsust tarvis on.
_________________
Teach a man to reason and he'll think for a lifetime
Common sense - so rare that it's a damn superpower
Vaadates paljude inimeste sõnavõtte siin ja mujal jääb üle ainult klassikuid tsiteerida - "I weep for humanity"
Kommentaarid: 106 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 86
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  C++ anomaalia
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.