Porównywanie floatów

0

Witam, mam pytanie. Wiem, że generalnie jest niebezpieczne porównywanie floatów w taki sposób, że w rzeczywistości reprezentują wartość przybliżoną. Ale gdy mam załóżmy sytuacje, że ustawiam danemu floatowi konkretną wartość

float a = 1.0f;

która zamieni się potem w coś typu... 0.992939429042943849387... albo coś podobnego.

To czy jest bezpieczne sprawdzenie, czy ten konkretny float ma akurat tą konkretną ustawioną wartość czy też nie?

if (a == 1.0f)

1.0f jest chyba stałym wyrażeniem w przypadku tego pierwszego i drugiego.

0

1

Jeżeli chcesz porównać floaty to zrób to tak:

epsilon = 0.005f
if (fabs(a - 1.0f) < epsilon) 

Lepiej sprawdzić do maksymalnego marginesu błędu - epsilon.

3
template<typename T>
bool fuzzyCompare(T a, T b) {
	return fabs(a-b) <= std::numeric_limits<T>::epsilon()*4*(fabs(a)+fabs(b));
}
0

Znam to... wielokrotnie już to robiłem, chodzi mi tylko o czysty fakt formalny, czy jeżeli przypiszę jakąś wartość dla floata (stałe wyrażenie), to czy mogę bezpiecznie porównać tą wartość z tym samym stałym wyrażeniem

edit: MarekR22 wyprzedził mnie, chodziło mi o rozwiązanie Madaoo.

5

Dopóki wartość nie jest wynikiem obliczeń to masz pewność, że porównanie da oczekiwany efekt.
A moje rozwiązanie jest tym samym co Madaoo z tą różnicą, że epsilon jest obliczany w locie (nie musisz się zastanawiać jaką wartość epsilon dobrać).

0

W sumie to może lepiej opisz po co to pytanie! Jaki jest twój pierwotny problem?

0

Aktualnie... Żaden ;)

Miałem zmienną float która miała zawsze stałą wartość od samego początku (stałe wyrażenie - 1.0f), albo miała wartość z przedziału 0.5f do 2.0f.

Zmienna ta reprezentuje to, jak bardzo mam zeskalowac dany obiekt.... nazwijmy to sobie zoom.

No i w przypadku, gdy ta wartosc ma dokladnie wartość wyrażenia 1.0f to nie chcę jej wykorzystywać do wyliczania width * zoom, height * zoom. Skoro zoom na wartość 1.0f (czyli nie dokładne 1) dla precyzji chciałem je wykluczyć w wyliczaniu width * zoom, height * zoom, a takze innych rzeczy, ze względu na nieprecyzyjność wartości 1.0f.

Głównie to chodzi o grafiki... nawet jak ustawie ich skale na .... 1.000001, to nastepuje masakra z dwuwymiarową teksturą, która... jakoś wygląda... ale nie za specjalnie, bo jest odrobinke zamazana.

1

1.0f nie zmieni się samo w coś innego, zawsze pozostanie równe 1.0f.
Ale wyniki działań nie są dokładne, czyli nie możesz zakładać że 123456.0f - 123455.0f jest dokładnie równe 1.0f (przykład z kosmosu).

w opisanym przypadku mógłbyś zrobić dokładnie to co chcesz: pomijać część obliczeń gdy jedną z wartości jest 1.0f - pod warunkiem że rzeczywiście czasami jest tyle równa, czyli taką wartość przypisujesz (a nie jest ona wynikiem innych wyliczeń). pytanie tylko ile na tym zyskasz, bo po pierwsze mnożenie przez 1.0f powinno być precyzyjne (czyli nie zmieniać drugiego czynnika), a po drugie na prędkości raczej nic też nie zyskasz.

0

Tu masz wątek gdzie umieściłem źródła związane z arytmetyką zmiennoprzecinkową.
http://4programmers.net/Forum/C_i_C++/256537-porownanie_double?p=1166421#id1166421

1 użytkowników online, w tym zalogowanych: 0, gości: 1