Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Usporedba double s 0.0

9 views
Skip to first unread message

Bernard Cupic

unread,
Jan 24, 2013, 9:31:25 AM1/24/13
to
Za početak, znam da se usporedba 2 double vrijednosti ne radi direktno
koristeći operator ==(), ali ima situacija i situacija.

Jedna od njih je usporedba sa varijablom koja je inicijalizirana
eksplicitno na neku vrijednost, tada bi operator ==() trebao vratiti
točnu vrijednost, ili se varam?

Napisao sam jedan mali test programčić:

#include <iostream>
#include <vector>

typedef std::vector<double> real_vector;

int main()
{
real_vector a(1500000, 0.0);

for(real_vector::const_iterator i=a.begin(); i != a.end(); ++i) {
if( *i != 0.0 ) {
std::cout << "Nije 0! => a[" << i - a.begin() << "] = "
<< *i << std::endl;
}
}
std::cout << "Gotovo\n";
return 0;
}

koji kod mene nikada ne nađe niti jednu vrijednost različitu od 0.0.
Probao sam i sa vrijednostima različitim od 0.0 i svejedno radi ispravno
tako da sam sklon vjerovati da se to može tako koristiti bez opasnosti,
ili se varam?

#uname -srm
Linux 3.6.11-1-ARCH x86_64 GNU/Linux

#g++ --version
g++ (GCC) 4.7.2

Koristio sam vector doubleova samo radi toga jer sam htio testirati i
njegov konstruktor jer mi tako nešto treba u mom algoritmu.

E sad, volio bih osvrt na ovu problematiku, a ako se nekome da, može
testirati gornji kod na nekoj drugoj platformi/kompajleru, baš me
zanimaju rezultati.

Bruno Babic

unread,
Jan 24, 2013, 10:54:14 AM1/24/13
to
On 24.1.2013. 15:31, Bernard Cupic wrote:
> koji kod mene nikada ne nađe niti jednu vrijednost različitu od 0.0.

Ja ne vidim razlog zasto bi *i ikada bio 0?

--
bbabic(a)globalnet.hr
2b||!2b?

Zeljko Vrba

unread,
Jan 25, 2013, 2:31:00 AM1/25/13
to
On 2013-01-24, Bernard Cupic <bernardT...@gmail.com> wrote:
>
> Jedna od njih je usporedba sa varijablom koja je inicijalizirana
> eksplicitno na neku vrijednost, tada bi operator ==() trebao vratiti
> točnu vrijednost, ili se varam?
>
Ako zanemarimo marginalne slucajeve (NaN, -0), == je bitwise comparison kao
i kod integera. Znaci x==y vraca true ako im je svaki bit identican. Nema
nikakve magije i nepreciznosti jer je mapping izmedju reprezentabilnih
brojeva i bitwise reprezentacije bijekcija.

E sad, da li ce tvoj program raditi ispravno ovisi o tome sto radis i s
kojim brojem usporedjujes. Recimo, 0.1 ne postoji, pa stoga sljedeca
petlja nikada nece zavrsiti:

double x = 0;
while (x != 10.0) x += 0.1;

S druge strane, uvijek ce biti x-x==0.0 ili 2*x == x+x. (Opet, ako zanemarimo
marginalne slucajeve, ovdje overflow.)

Bernard Cupic

unread,
Jan 25, 2013, 3:24:28 AM1/25/13
to
To sam i mislio.
Čim uključiš matematičke operacije s pomičnim zarezom više ne možeš
vršiti direktne usporedbe operatorom ==().

Imam neki skup u koji smještam non-zero vrijednosti pa sam, u sklopu tog
algoritma, krenuo provjeravati je li varijabla jednaka 0.0 ili je
obrađena.
Tako sam i došao u ovu nedoumicu.

Bernard Cupic

unread,
Jan 25, 2013, 3:27:52 AM1/25/13
to
Na Thu, 24 Jan 2013 16:54:14 +0100, Bruno Babic napisao:

> On 24.1.2013. 15:31, Bernard Cupic wrote:
>> koji kod mene nikada ne nađe niti jednu vrijednost različitu od 0.0.
>
> Ja ne vidim razlog zasto bi *i ikada bio 0?

Ne vjerujem da ti to trebam pojašnjavati!
Dereferenciranje iteratora vektora vraća što?
Vektor je inicijaliziran nulama, što znači da su svi članovi == 0.

Šta nije jasno?

Bruno Babic

unread,
Jan 25, 2013, 3:14:25 AM1/25/13
to
On 24.1.2013. 16:54, Bruno Babic wrote:
> On 24.1.2013. 15:31, Bernard Cupic wrote:
>> koji kod mene nikada ne nađe niti jednu vrijednost različitu od 0.0.
>
> Ja ne vidim razlog zasto bi *i ikada bio 0?

Oops, nisam bas detaljno gledao... igrnoriraj ovaj moj komentar :)

--
bbabic(a)globalnet.hr
2b||!2b?

Bruno Babic

unread,
Jan 25, 2013, 3:16:44 AM1/25/13
to
On 25.1.2013. 9:24, Bernard Cupic wrote:
> Čim uključiš matematičke operacije s pomičnim zarezom više ne možeš
> vršiti direktne usporedbe operatorom ==().

Meni su takve stvari isto isle na zivce pa sam zakljucio da mi je
jednostavnije da takve probleme rjesavam sa integerima, tj. decimalne
vrijednosti (sa poznatim i konacnim brojem decimala) spremam u integere
koje onda samo prilikom ispisa dijelim sa koliko je vec potrebno.
U tom slucaju operator == radi i vise nego dovoljno dobro, jedino sto
gubis decimale nakon nekog mjesta, ali ako se ne bavis NASA-inim
izracunima, to ti ionako nije vazno :)

--
bbabic(a)globalnet.hr
2b||!2b?

Davorin Vlahovic

unread,
Jan 25, 2013, 5:34:44 AM1/25/13
to
[Thu, 24 Jan 2013 14:31:25 +0000 (UTC)] Bernard Cupic je napisao/la:
> Za početak, znam da se usporedba 2 double vrijednosti ne radi direktno
> koristeći operator ==(), ali ima situacija i situacija.
>
> Jedna od njih je usporedba sa varijablom koja je inicijalizirana
> eksplicitno na neku vrijednost, tada bi operator ==() trebao vratiti
> točnu vrijednost, ili se varam?

Uvijek mozes "popraviti" operator da zapravo bude oduzimanje i provjera je li
apsolutni rezultat manji od neke okoline za koju ti je bitna preciznost.

Tipa:

== -> double r=fabs(a-b); return (r<preciznost)?true:false ;

Samo pripazi na akumulaciju gresaka, redosljed operacija (prvo obradi brojeve
bliskog reda velicine) i tako neke stvari.



--
"The future is already here — it's just not very evenly distributed."
- William Gibson

Bernard Cupic

unread,
Jan 25, 2013, 6:49:01 AM1/25/13
to
Na Fri, 25 Jan 2013 10:34:44 +0000, Davorin Vlahovic napisao:

> [Thu, 24 Jan 2013 14:31:25 +0000 (UTC)] Bernard Cupic je napisao/la:
>> Za početak, znam da se usporedba 2 double vrijednosti ne radi direktno
>> koristeći operator ==(), ali ima situacija i situacija.
>>
>> Jedna od njih je usporedba sa varijablom koja je inicijalizirana
>> eksplicitno na neku vrijednost, tada bi operator ==() trebao vratiti
>> točnu vrijednost, ili se varam?
>
> Uvijek mozes "popraviti" operator da zapravo bude oduzimanje i provjera
> je li apsolutni rezultat manji od neke okoline za koju ti je bitna
> preciznost.
>
> Tipa:
>
> == -> double r=fabs(a-b); return (r<preciznost)?true:false ;
>
> Samo pripazi na akumulaciju gresaka, redosljed operacija (prvo obradi
> brojeve bliskog reda velicine) i tako neke stvari.

Nesklon sam takvim popravcima. Više volim eksplicitnost, onda imam
i jednu i drugu varijantu pa znam šta biram. Ne volim kad se stvari
dešavaju iza mojih leđa zato što je netko mislio da ja ne znam šta želim.

Ako je
bool operator ==(double lhs, double rhs), onda očekujem to ponašanje,
ako je to funkcija
bool isEqual(double lhs, double rhs, double tol=defaultPreciznost)
onda znam šta očekujem čim vidim potpis.

Bernard Cupic

unread,
Jan 25, 2013, 6:51:38 AM1/25/13
to
Radim s 3D grafikom, NURBS-i, scene graph, OpenGL isl.

Mislim da mi taj tvoj pristup ovdje ne bi odgovarao :)

Zeljko Vrba

unread,
Jan 25, 2013, 7:29:04 AM1/25/13
to
On 2013-01-25, Davorin Vlahovic <nr...@ylf.krs.ref.rh> wrote:
>
> Uvijek mozes "popraviti" operator da zapravo bude oduzimanje i provjera je li
> apsolutni rezultat manji od neke okoline za koju ti je bitna preciznost.
>
> Tipa:
>
>== -> double r=fabs(a-b); return (r<preciznost)?true:false ;
>

Ovo ce raditi samo sa brojevima ciji je red velicine veci od epsilona.
Ili, opcenitije, ovo nece dobro raditi ako imas veliki dinamicki range
ulaznih podataka i rezultata.

Zeljko Vrba

unread,
Jan 25, 2013, 7:33:00 AM1/25/13
to
On 2013-01-25, Bernard Cupic <bernardT...@gmail.com> wrote:
>
> To sam i mislio.
> Čim uključiš matematičke operacije s pomičnim zarezom više ne možeš
> vršiti direktne usporedbe operatorom ==().
>
Ma... to je rule of thumb..


> Imam neki skup u koji smještam non-zero vrijednosti pa sam, u sklopu tog
> algoritma, krenuo provjeravati je li varijabla jednaka 0.0 ili je
> obrađena.

To slobodno napravis s ==.

Davorin Vlahovic

unread,
Jan 25, 2013, 8:58:37 PM1/25/13
to
Nemas tu srecu zivjeti u takvom svijetu. Problem je sama priroda decimalnih
brojeva zapisanih po ieee754.

Davorin Vlahovic

unread,
Jan 25, 2013, 8:58:59 PM1/25/13
to
Naravno. Zato moras shvacati sto radis :)

Zeljko Vrba

unread,
Jan 26, 2013, 5:35:15 AM1/26/13
to
On 2013-01-25, Bernard Cupic <bernardT...@gmail.com> wrote:
>
> Nesklon sam takvim popravcima. Više volim eksplicitnost, onda imam
> i jednu i drugu varijantu pa znam šta biram. Ne volim kad se stvari
> dešavaju iza mojih leđa zato što je netko mislio da ja ne znam šta želim.
>
Srecom nije moguce redefinirati operatore nad primitivinim tipovima,
tipa ==(float, float) :)

Zeljko Vrba

unread,
Jan 26, 2013, 5:36:28 AM1/26/13
to
On 2013-01-26, Davorin Vlahovic <nr...@ylf.krs.ref.rh> wrote:
>>
>> Ako je
>> bool operator ==(double lhs, double rhs), onda očekujem to ponašanje,
>> ako je to funkcija
>> bool isEqual(double lhs, double rhs, double tol=defaultPreciznost)
>> onda znam šta očekujem čim vidim potpis.
>
> Nemas tu srecu zivjeti u takvom svijetu. Problem je sama priroda decimalnih
> brojeva zapisanih po ieee754.
>

??????

Davorin Vlahovic

unread,
Jan 26, 2013, 8:07:41 AM1/26/13
to
Zaboravi :)
0 new messages