checking for close enough floating point values.

P

pereges

Let's say I have two doubles:

double a, b;

a = 9.35678910034592
b = 9.35678925602334

Obviously, a < b but lets say I just want to check up to 6 places
after the decimal. I want to check if the condition a >= b is
satisfied. I have a tolerance value:

#define EPSILON 0.000001

Is this a good way to check for a >= b

if( fabs(a-b) <= EPSILON)
....
 
V

vippstar

Let's say I have two doubles:

double a, b;

a = 9.35678910034592
b = 9.35678925602334

Obviously, a < b but lets say I just want to check up to 6 places
after the decimal. I want to check if the condition a >= b is
satisfied. I have a tolerance value:

#define EPSILON 0.000001

Is this a good way to check for a >= b

if( fabs(a-b) <= EPSILON)
...
Question 14.5 of the C-FAQ.
<http://c-faq.com/>
 
W

Walter Roberson

Let's say I have two doubles:
double a, b;
a = 9.35678910034592
b = 9.35678925602334
Obviously, a < b but lets say I just want to check up to 6 places
after the decimal. I want to check if the condition a >= b is
satisfied. I have a tolerance value:
#define EPSILON 0.000001
Is this a good way to check for a >= b
if( fabs(a-b) <= EPSILON)
...

That is a typical way to check whether values are "close enough"
to being equal.

However, you should be aware that this is -not- a test for
equality up to the 6th decimal place. There is no exact representation
for 0.000001 in binary floating point arithmetic, so chances
are that instead if you use that EPSILON, what you will end up doing is
checking whether they are equal to within
9.99999999999999954748111825886258685613938723690807819366455078125e-07

That's a number slightly less than 0.000001. This could make a difference
if your a and b values were (for example) on the order of .00009 themselves.
 
B

Barry Schwarz

Let's say I have two doubles:

double a, b;

a = 9.35678910034592
b = 9.35678925602334

Obviously, a < b but lets say I just want to check up to 6 places
after the decimal. I want to check if the condition a >= b is
satisfied. I have a tolerance value:

#define EPSILON 0.000001

Is this a good way to check for a >= b

if( fabs(a-b) <= EPSILON)
...

This checks for a == b, not a >= b.

if (a + EPSILON >= b) would be the corresponding check for >=.

However, you should read 14.5 in the c-faq (www.c-faq.com) to see why
an unscaled EPSILON is a bad idea.


Remove del for email
 
P

pereges

This checks for a == b, not a >= b.

if (a + EPSILON >= b) would be the corresponding check for >=.

However, you should read 14.5 in the c-faq (www.c-faq.com) to see why
an unscaled EPSILON is a bad idea.

So do you think it will be better to use the relative difference
method as suggested in the C faq 14.5 ?

#define Abs(x) ((x) < 0 ? -(x) : (x))
#define Max(a, b) ((a) > (b) ? (a) : (b))

double RelDif(double a, double b)
{
double c = Abs(a);
double d = Abs(b);

d = Max(c, d);

return d == 0.0 ? 0.0 : Abs(a - b) / d;
}


....
to check for a >= b,

if(RelDif(a, b) <= TOLERANCE || a > b)
...

Btw the floating point data that I'm reading has 6 places after the
decimal point so I though I would take a tolerance value of 0.000001.
 
P

pereges

I don't know why a seperate macro has been written for finding
absolute value. Was it not possible to use fabs() ?

#define Abs(x) ((x) < 0 ? -(x) : (x))
 
B

Bartc

Barry Schwarz said:
This checks for a == b, not a >= b.

if (a + EPSILON >= b) would be the corresponding check for >=.

What about:

if ( a>b || (fabs(a-b)<=EPSILON) )

for a>=b ? This would be faster when a is normally expected to be greater
than b.
 
B

Barry Schwarz

So do you think it will be better to use the relative difference
method as suggested in the C faq 14.5 ?

snip

Btw the floating point data that I'm reading has 6 places after the
decimal point so I though I would take a tolerance value of 0.000001.

If you can guarantee that all the data will be within a certain range
then you don't need to scale based on the current value. But what
happens when one set of values is near 1e-6 and another is near 1e10?
That is the point I thought the faq was trying to make.


Remove del for email
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top