numerical precision of a double

• 03-11-2008
mc61
numerical precision of a double
Dear C experts,

Could anyone tell me what the numerical precision of a double is in C? I read about the smallest and largest numbers I can store in a double, but what I really need to know is how many significant digits after the decimal point are "to be trusted"? Is it a 16-digit mantissa in scientific notation?

Besides understanding this issue, I have a practical need to know this. I want to use a function to compare doubles. Something like

Code:

#define Abs(x)    ((x) < 0 ? -(x) : (x))
#define Max(a, b) ((a) > (b) ? (a) : (b))
double RelativeDifference(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;
}

So, a good condition for two doubles to be the same would be

Code:

if ( RelativeDifference(x,y) < TOLERANCE )
Thus, what is a good value for TOLERANCE? 1E(-16)?

Thank you very much,

mc61
• 03-11-2008
matsp
What you really want is "epsilon", which is the "smallest difference between two numbers in the current range". If you are working on numbers that are very large, epsilon would be a rather large number, 1E200 for example would have a epsilon of about 1E185 if your numbers are in the order of 1E-200, then 1E-16 is quite enormous, and epsilon would be around 1E-215.

--
Mats
• 03-11-2008
grumpy
Epsilon may be obtained as FLT_EPSILON (for float), DBL_EPSILON (for double), or LDBL_EPSILON (for long double). These macros may be found in the standard C header, <float.h>.
• 03-11-2008
mc61
Thanks.

I thought I was sorting out the issue of large vs small numbers by using the relative difference. In other words, when one divides by one of the numbers (assuming the other is of the same order), then the relative difference is of order 0 (i.e. 0.xxxx).

You point out that something of order 200 (1E200) would have an epsilon of 185 (1E185), while something of order -200 would have an epsilon of -215. Thus, you are looking at an order difference of -15 in both cases. I think this means that in my definition of "relative difference" the tolerance would be 1E-15 (i.e. a fractional part of 15 digits in scientific notation). That makes sense.

mc61
• 03-11-2008
tabstop
The epsilons grumpy mentions are the mats' "epsilon" for the number 1; since you're worried about equality, you should be checking whether |(c/d)-1| < dbl_epsilon.
• 03-11-2008
mc61
matsp, grumpy, and tabstop,

Sorry, my second post crossed paths with grumpy's and tabstop's...

Thanks! Excellent!! You guys gave me exactly what I was looking for.

Thanks again,

mc61
• 03-11-2008
iMalc
The D language has the best floating point equality testing routines I have ever seen.