Re: comparing doubles for equality



Thad Smith wrote:
CBFalconer wrote:
Thad Smith wrote:
John Smith wrote:

This code for the comparison of fp types is taken from the C FAQ.
Any problems using it in a macro?

/* compare 2 doubles for equality */
#define DBL_ISEQUAL(a,b) (fabs((a)-(b))<=(DBL_EPSILON)*fabs((a)))
This construction is misleading and I would never use it, because
the implied function, determining whether two doubles are equal,
is not an accurate description of the returned value.

How about:

#define DUNEQUAL(a, b) (fabs((a)-(b)) > (DBL_EPSILON)*fabs((a)))

with a caveat against passing an a with side effects.

That misses the point. The only true equality test is given by
a==b. If you need an epsilon, fine, but you should make it
explicit. DBL_EPSILON isn't necessarily the correct choice for a
particular application. In fact, the two tests above may not
provide any advantage over a strict equality.

No, I think you miss the point. Floating point is inherently an
approximation, and the above says that anything within the
resolution (i.e. the approximation) is to be considered equal. Any
time you see (a == b) for floating point operands, it is probably a
bug. For example:

for (a = 1.0; a != 0; a -= 0.1) dosomethingwith(a);

will probably not behave. While:

for (a = 1.0; !DUNEQUAL(a, 0.0); a -= 0.1) dosomethingwith(a);

will behave. Of course:

for (a = 1.0; a > 0; a -= 0.1) dosomethingwith(a);

may behave. But it is a crapshoot whether it does an extra cycle.

--
Merry Christmas, Happy Hanukah, Happy New Year
Joyeux Noel, Bonne Annee.
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>

.