Wpis z mikrobloga

#programowanie może być #cpp i #it

Naświetli ktoś po chłopsku porównanie dwóch wartości float?
To znaczy, nie robi się


float x;
x = 1,2;
if (x==1,2) {
//tu coś
}

tylko:

float x;
x = 1,2;
if (fabsf(a-b) < FLT_EPSILON) {
//tu coś
}

gdzie FLTEPSILON jest epsilonem maszynowym

Rozumiem - ale nie do końca. ( ͡° ͜ʖ ͡°)
Chodzi o to, że float może mieć trochę inną wartość jakiej się spodziewamy.

  • 17
@defoxe: tak, procesory mają ograniczoną dokładność. Poczytaj o IEEE 754.

może się okazać, że x to 1,2000000002 a porównujesz z 1,2000000001... no to nie będzie równe.
ale jeśli różnica między x a porównywaną liczbą jest mniejsza od epsilona maszynowego (charakterystyczna wartość dla każdego typu procesora, mozna w matlabie sprawdzic sobie ;)) to +/- będziesz mógł założyć że są równe.
tylko nie wiem dlaczego po przecinku gdzieś daleko może mieć "błędy"


@defoxe: To tak jakbyś chciał zapisać 1/3 w systemie dziesiętnym mając do dyspozycji ograniczoną ilość miejsca na kartce - możesz napisać 0,333333333333333, ale nigdy nie uzyskasz dokładnie 1/3 tylko jakieś przybliżenie.
Bo przecież jeśli deklarowana jest zmienna i podawana jest jej wartość, to powinna być właśnie taka a nie inna.


@defoxe: Jeżeli taką wartość da się zapisać bezstratnie w systemie binarnym na określonej liczbie bitów to tak będzie, a jeżeli nie to kompilator wpisze tam najlepsze przybliżenie tej liczby.
Poza tym zazwyczaj liczby do porównania nie są wpisywane bezpośrednio tylko są to wyniki jakiś skomplikowanych obliczeń. Co więcej zmienna float ma "bardzo
@g500s: czyli dobrze rozumiem chyba... Jednak odczyt z czujników (gdy zwracany jest float a porównujemy do float) powinien być bezpieczny i wystarczy if (fabsf(a-b) < 0.01f)
Jeśli oczywiście wystarcza taka dokładność.

Epsilon maszynowy zmienia się od typu procesora?
Zauważyłem, że

#define FLT_EPSILON 1.19209290E-07F
natomiast zakres float -3.4E38 do 3.4E38

To niesamowite w sumie, że na takich zakresach
1 + ε = 1

ma być kropka a nie przecinek w c++


@