float ... problem czy moj blad ?
Ostatnio zmodyfikowano 2015-08-02 01:42
k4boc Temat założony przez niniejszego użytkownika |
float ... problem czy moj blad ? » 2015-08-01 13:03:59 #include <iostream> using namespace std; int main() { float liczba; cout << "Podaj liczbe 7.77 by zakonczyc petle. : "; cin >> liczba; cout << endl; if( liczba == 7.77 ) { cout << "Udalo sie za pierwszym razem."; return 0; } do { cout << "sprobuj jeszcze raz :) : "; cin >> liczba; cout << endl; } while( liczba != 7.77 ); cout << "nie za pierwszym ale brawo !"; return 0; }
dla calkowitych (oczywiscie ze zmiana warunkow) zadziala, niestety tutaj petla nie jest przerywana mimo podania prawidlowej liczby (7.77). Z góry dziękuję za pomoc i wyjaśnienie ;) |
|
pekfos |
» 2015-08-01 13:07:34 Porównujesz liczby różnych precyzji. Zmiennoprzecinkowych liczb prawie nigdy nie powinno się porównywać przez ==. |
|
DejaVu |
» 2015-08-01 19:17:04 7.77f => float 7.77 => double
A tak poza tym to jak wyżej. |
|
Gibas11 |
» 2015-08-02 00:58:32 Pomijając to co napisano wyżej, do porównywania doubli używam tej funkcji: bool cmp( double a, double b ) { return fabs( a - b ) < EPSILON; }
A na początku programu dorzucam jeszcze definicję stałej EPSILON (im więcej zer po przecinku, przed jedynką, tym większa dokładność porównania): #define EPSILON 0.000000001 Jeżeli chcesz porównywać jeszcze floaty po definicji funkcji "cmp" wyżej dorzuć jeszcze bool cmp( double a, float b ) { return fabs( a - b ) < EPSILON; } bool cmp( float a, double b ) { return fabs( a - b ) < EPSILON; } bool cmp( float a, float b ) { return fabs( a - b ) < EPSILON; }
I wyjaśnionko, ponieważ typy zmiennoprzecinkowe często na końcu mają jakieś mikroskopijne odstępstwa, których nie oczekiwaliśmy, porównanie == odpada, w zastosowanej przeze mnie funkcji najpierw wyliczana jest wartość bezwzględna różnicy dwóch liczb porównywanych liczb, a następnie sprawdzane jest czy różnica ta jest mniejsza od precyzji z jaką sprawdzamy "równość", jeżeli tak - zwracane jest true, a jeżeli nie - false. |
|
Elaine |
» 2015-08-02 01:42:17 Przy tym epsilonie różnica jednego ulpa dla liczb ≥ 8388608 spowoduje, że liczby zostaną uznane za nierówne mimo tego, że względna ich różnica jest praktycznie taka sama, jak między, np. 0.33333333333333331 a 0.33333333333333337. Od tego nie da się uwolnić zmieniając epsilon, zmieni się w ten sposób tylko wartość, od której ten problem zaczyna się pojawiać. Rozwiązaniem jest obliczenie różnicy w ulpach i na tej podstawie określenie, czy liczby są "wystarczająco równe". |
|
« 1 » |