Thanks for your answers, they helped me a lot. I've read these materials:first and second
The answer is to use my own function for relative comparison:
bool areEqualRel(float a, float b, float epsilon) {
return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
}
This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.
#include <iostream>
#include <limits>
#include <algorithm>
using std::cout;
using std::max;
bool areEqualAbs(float a, float b, float epsilon) {
return (fabs(a - b) <= epsilon);
}
bool areEqual(float a, float b, float epsilon) {
return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
}
bool areEqualRel(float a, float b, float epsilon) {
return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
}
int main(int argc, char *argv[])
{
cout << "minimum: " << FLT_MIN << "\n";
cout << "maximum: " << FLT_MAX << "\n";
cout << "epsilon: " << FLT_EPSILON << "\n";
float a = 0.0000001f;
float b = 0.0000002f;
if (areEqualRel(a, b, FLT_EPSILON)) {
cout << "are equal a: " << a << " b: " << b << "\n";
}
a = 1000001.f;
b = 1000002.f;
if (areEqualRel(a, b, FLT_EPSILON)) {
cout << "are equal a: " << a << " b: " << b << "\n";
}
}
1e-10
and1e-15
and-1e-10
as all equal. There is no single "correct" way to compare floating point numbers for "closeness". – Gardening