473,381 Members | 1,508 Online

# Efficient double comparison

Hello all,

I would like to solicit suggestions on how to most efficiently accomplish
something. I have profiled the project I'm working on and have found that
calls to fabs() are taking a very substantial amount of time. fabs() is
being used in the following manner:

double a, b;

a = get_a_value();
b = get_another_value();

if (fabs(a - b) > 1E-9)
// Do "not equal" stuff
else
// Do "equal" stuff

So, we're simply comparing two doubles for equality and making allowances
for inexact numeric representation.

Of course, we could save time by reducing the number of comparisons. But,
unfortunately, we do need all of the comparisons we're making - none are
redundant or unused. So... Can anybody out there suggest a more efficient
way of accomplishing these comparisons?

Thanks,
Dave
Jul 22 '05 #1
2 15148
"Dave" <be***********@yahoo.com> wrote

Hello all,

I would like to solicit suggestions on how to most efficiently accomplish
something. I have profiled the project I'm working on and have found that
calls to fabs() are taking a very substantial amount of time. fabs() is
being used in the following manner:

double a, b;

a = get_a_value();
b = get_another_value();

if (fabs(a - b) > 1E-9)
// Do "not equal" stuff
else
// Do "equal" stuff

So, we're simply comparing two doubles for equality and making allowances
for inexact numeric representation.

Of course, we could save time by reducing the number of comparisons. But,
unfortunately, we do need all of the comparisons we're making - none are
redundant or unused. So... Can anybody out there suggest a more efficient
way of accomplishing these comparisons?

You can always do something like this:

inline bool simpleFuzzyEq(const double & v1, const double & v2, const double &
epsilon)
{
const double diff = v1 - v2;

return diff < epsilon && diff > -epsilon;
}

The extra comparison is far less expensive than a call to fabs() and most
compilers will inline this to something extremely tight.

As a side note, a fuzzy equality test with an absolute epsilon has an extremely
limited scope and doesn't behave intuitively if the magnitudes of a comparand is
very large.

Claudio Puviani
Jul 22 '05 #2
Hi,

inline bool simpleFuzzyEq(const double & v1, const double & v2, const double
&
epsilon)
{
const double diff = v1 - v2;

return diff < epsilon && diff > -epsilon;
}
The extra comparison is far less expensive than a call to fabs() and most
compilers will inline this to something extremely tight.
This is something I absolutely cannot agree about, at least for Intel 80x86
architecture. FABS operation done in 80x86 FPU takes exactly 1 cycle, and
also pairs with the next operation (if they're not dependent). Practically -
it is free. Comparison between 2 floating point numbers is a complex thing
on the other hand. It can take as much as 4 cycles, plus extra instructions
to copy the result from FPU registers to CPU registers (to actually do the
conditional jump based on comparison result). Not to say that in the code
above there is an extra unary negation op, which has usually the same
complexity as FABS alone. And an extra '&&' operation...

I don't know other CPU architectures, but I think it's the same way round.

On 80x86, if precision up to 15th digit is not very important, I'd suggest
switching to float data and using _control87() to force FPU to work in
24-bit precision mode. _control87() is non-standard, but present in most
80x86 compilers libraries:

_control87(_PC_24, MCW_PC); // reduce precision
// here put plenty of intensive floating point operations. They'll work much
faster

_control87(_PC_53, MCW_PC); // restore precision

Best regards,
Marcin

Użytkownik "Claudio Puviani" <pu*****@hotmail.com> napisał w wiadomości
news:E_**********************@news4.srv.hcvlny.cv. net...
"Dave" <be***********@yahoo.com> wrote
Hello all,

I would like to solicit suggestions on how to most efficiently accomplish
something. I have profiled the project I'm working on and have found that
calls to fabs() are taking a very substantial amount of time. fabs() is
being used in the following manner:

double a, b;

a = get_a_value();
b = get_another_value();

if (fabs(a - b) > 1E-9)
// Do "not equal" stuff
else
// Do "equal" stuff

So, we're simply comparing two doubles for equality and making allowances
for inexact numeric representation.

Of course, we could save time by reducing the number of comparisons. But,
unfortunately, we do need all of the comparisons we're making - none are
redundant or unused. So... Can anybody out there suggest a more efficient
way of accomplishing these comparisons?

You can always do something like this:

inline bool simpleFuzzyEq(const double & v1, const double & v2, const double
&
epsilon)
{
const double diff = v1 - v2;

return diff < epsilon && diff > -epsilon;
}

The extra comparison is far less expensive than a call to fabs() and most
compilers will inline this to something extremely tight.

As a side note, a fuzzy equality test with an absolute epsilon has an
extremely
limited scope and doesn't behave intuitively if the magnitudes of a
comparand is
very large.

Claudio Puviani

Jul 22 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.