Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

float ... problem czy moj blad ?

Ostatnio zmodyfikowano 2015-08-02 01:42
Autor Wiadomość
k4boc
Temat założony przez niniejszego użytkownika
float ... problem czy moj blad ?
» 2015-08-01 13:03:59
C/C++
#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 ;)
P-135573
pekfos
» 2015-08-01 13:07:34
Porównujesz liczby różnych precyzji. Zmiennoprzecinkowych liczb prawie nigdy nie powinno się porównywać przez ==.
P-135574
DejaVu
» 2015-08-01 19:17:04
7.77f => float
7.77  => double

A tak poza tym to jak wyżej.
P-135588
Gibas11
» 2015-08-02 00:58:32
Pomijając to co napisano wyżej, do porównywania doubli używam tej funkcji:
C/C++
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
C/C++
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.
P-135595
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".
P-135596
« 1 »
  Strona 1 z 1