Categories:

.NET (961)

C (387)

C++ (185)

CSS (84)

DBA (8)

General (31)

HTML (48)

Java (641)

JavaScript (220)

JSP (109)

JUnit (31)

MySQL (297)

Networking (10)

Oracle (562)

Perl (48)

Perl (9)

PHP (259)

PL/SQL (140)

RSS (51)

Software QA (28)

SQL Server (5)

Struts (20)

Unix (2)

Windows (3)

XHTML (199)

XML (59)

Other Resources:

What is a good way to check for ``close enough'' floating-point equality?

Q

What is a good way to check for ``close enough'' floating-point equality?

✍: Guest

A

Since the absolute accuracy of floating point values varies, by definition, with their magnitude, the best way of comparing two floating point values is to use an accuracy threshold which is relative to the magnitude of the numbers being compared. Rather than

double a, b;

...

if(a == b) /* WRONG */

use something like

#include <math.h>

if(fabs(a - b) <= epsilon * fabs(a))

where epsilon is a value chosen to set the degree of ``closeness'' (and where you know that a will not be zero). The precise value of epsilon may still have to be chosen with care: its appropriate value may be quite small and related only to the machine's floating-point precision, or it may be larger if the numbers being compared are inherently less accurate or are the results of a chain of calculations which compounds accuracy losses over several steps. (Also, you may have to make the threshold a function of b, or of both a and b.)

A decidedly inferior approach, not generally recommended, would be to use an absolute threshold:

if(fabs(a - b) < 0.001) /* POOR */

Absolute ``fuzz factors'' like 0.001 never seem to work for very long, however. As the numbers being compared change, it's likely that two small numbers that should be taken as different happen to be within 0.001 of each other, or that two large numbers, which should have been treated as equal, differ by more than 0.001 . (And, of course, the problems merely shift around, and do not go away, when the fuzz factor is tweaked to 0.005, or 0.0001, or any other absolute number.)

Doug Gwyn suggests using the following ``relative difference'' function. It returns the relative difference of two real numbers: 0.0 if they are exactly the same, otherwise the ratio of the difference to the larger of the two.

#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;

}

Typical usage is

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

2015-06-26, 1038👍, 0💬

Popular Posts:

Can we have shared events ? Yes, you can have shared event’s note only shared methods can raise shar...

Write down the equivalent pointer expression for referring the same element a[i][j][k][l]? a[i] == *...

How To Remove the Top White Space of Your Web Page? - CSS Tutorials - Introduction To CSS Basics The...

Where Do You Download JUnit? Where do I download JUnit? I don't think anyone will ask this question ...

What is Concern in AOP? gA concern is a particular goal, concept, or area of interesth There are m...