Porównywanie i przyrównywanie zmiennych double

0

Witam, tworzę program, który analizuje spore zbiory liczb zmiennoprzecinkowych (wczytywane z pliku). W tym celu program musi potrafić porównywać ( >, <= itd. ) oraz przyrównać ( == ) do siebie liczby double. Czy mam gwarancję, że w c++ poniższe funkcje dadzą wynik w 100% przypadków zgodny z matematycznym wynikiem poszczególnych działań ?

const double Eps = 0.00001;

bool doubleEquals(double left, double right, double epsilon) {
  return (fabs(left - right) < epsilon);
}

bool doubleLess(double left, double right, double epsilon, bool orequal = false) {
  if (fabs(left - right) < epsilon) {
    return (orequal);
  }
  return (left < right);
}

bool doubleGreater(double left, double right, double epsilon, bool orequal = false) {
  if (fabs(left - right) < epsilon) {
    return (orequal);
  }
  return (left > right);
} 

Przykład użycia:

    double t1 = 1.5122;
    double t2 = 1.5123;
    if (doubleGreater(t1, t2, Eps, 1)) cout << t1 << " " << t2 << "  t1 >= t2" << endl; 

Liczby, które mój program przetwarza nigdy nie mają więcej niż 5 cyfr po przecinku, np.: 1.12345, 1.4, 10.723, 101.034, 1.54324 itp.

0

Pytanie dodatkowe: na co powinienem uważać dokonując w ten sposób porównań double ?

0

Nie jestem pewien ile bitow jest przeznaczone na ceche i mantyse przy double, ale samo double zajmuje 64 bity, wiec precyzja dzialan jest do kilkunastu/-dziesiecu cyfr po przecinku, tak wiec wyniki beda zgodne dla tak "malych" liczb.

0

Nie są w 100 % zgodne z matematyką, może wyjść: a=b, b=c i a=/=c. Dodatkowo nie działa dla małych liczb.

0

@Zjarek - jesteś pewien? Przypisania powinny być równoważne kopiowaniu bit po bicie (jak będę miał czas to sprawdzę jak to kompilatory rozwiązują, ale na logikę...)?

Ale na przykład

a = 12345;
b = sqrt(a);
b = b * b;
if (a == b) { /* do stuff */ }

Praktycznie na pewno się nie wykona (jeśli double z C++ są zgodne z IEEE to powinny się różnić o dokładnie -0.0000000000018189894035458565)

0

Uściślając część całkowita liczb na których operuje nigdy nie jest większa od 200, część ułamkowa ma maksymalnie 5 miejsc po przecinku. Odnośnie praw matematyki głównie miałem na myśli same przyrównanie, tj. pewność, że program nigdy nie stwierdzi że np. 100.00001 jest mniejsze od 100. Rozumiem, że w takim wypadku nie mam się o co martwić. Dzięki za odpowiedzi.

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