2010-09-22 20 views
8

po prostu wpadł na tej linii kodu:Czy jeśli (podwójne) prawidłowe C++?

if(lineDirection.length2()){...} 

gdzie length2 zwracającej double. To trochę zagadki, że 0,0 jest równoważne 0, NULL i/lub false.

Czy jest to część standardu C++, czy jest to niezdefiniowane zachowanie?

+1

Należy również zwrócić uwagę na NaN –

Odpowiedz

9

Jest to bardzo standardowe zachowanie (Boolean Conversion)

$ 4,12/1 - „rvalue arytmetyki, wyliczenia wskaźnika lub wskaźnik do typu członek może być przekształcony w rvalue z type bool. Wartość zero, wartość wskaźnika pustego lub wartość zerowa wartość wskaźnika jest konwertowana na wartość false; każda inna wartość jest konwertowana na wartość true. "

5

Tak - porównanie jest przeciwne zeru (0.0) i zwraca wartość false, jeśli wynik jest równy zero, i prawda w przeciwnym razie.

Zachowanie jest dziedziczone z C, które traktuje równoważne porównanie w ten sam sposób.

0

Porównując bez operatorów, porównujesz "przeciw true", tak że każdy typ zmiennej jest sprawdzany jako boolean (prosty przypadek) lub inny. Typy liczbowe mają fałszywą wartość zdefiniowaną jako "0", "0,0" lub mniej, więc gdy porównasz je z wartością "prawda", twoje porównanie zwróci wartość false.

7

Warto zauważyć, że ten kod jest niezwykle kruchy w przypadku reprezentacji zmiennoprzecinkowej. Ten kod zadziała, jeśli i tylko wtedy, gdy wartość zmiennoprzecinkowa wynosi dokładnie 0, co w większości przypadków jest mało prawdopodobne. Może nie być w tym konkretnym przypadku, ale z pewnością powinno być udokumentowane/skomentowane, jeśli tak.

W praktycznie wszystkich innych sytuacjach musisz zdecydować o numerze "epsilon value", który definiuje zakres liczb zmiennoprzecinkowych, które uważasz za "takie same" - w przeciwnym razie twoje porównania mogą zaskoczyć Cię w rogu (i często w innym miejscu)) przypadki.

+3

+1 za wskazanie kruchości kodu. Spowoduje to złamanie wielu warunków, które mogą nie być oczywiste: 'double d = 0,0/-1,0; jeśli (d) 'daje fałsz, jako' -0.0! = 0.0', a to samo dotyczy wielu innych operacji, które mogą dać wystarczająco bliskie wartości '0', która nie jest ** dokładnie **' 0.0' –

+0

być pewnym. Czy kod "double x = 0.0; if (x) {cout <<" x nie jest pusty ";}" print "x nie jest puste"? –

+3

@David Rodríguez - dribeas: Nie, -0,0 == 0.0', nawet jeśli wzory bitowe byłyby inne. Jest to niezwykle ważne. Wyrażenie '(x == 0.0 || (1.0/x))' _nie_ oceni '1.0/x', gdy spowoduje to dzielenie przez zero. – MSalters

0

Jeśli length2 zwraca 0,0, zostanie uznane za fałszywe. Ale z takim porównaniem możesz uzyskać zaskakujący wynik. Lepiej użyj wartości epsilon, jak zasugerował MadKeithV podczas porównywania zmiennoprzecinkowego.

Powiązane problemy