11-15-2006 04:31 AM
11-15-2006 04:56 AM
11-15-2006 05:07 AM
11-15-2006 05:17 AM
11-15-2006 07:40 AM
11-16-2006 02:13 AM
Thanks for your reply, John Cameron,
I did not know about the FP_Compare function. I find it very useful (and also the other FP_... -functions in the toolbox library).
11-16-2006 08:19 AM
Hi Mawie,
All advices that have already been given to you are true ! The exact explanation of all this is the way your machine codes numbers (floating points). Just have a look at this link here.
Regards,
12-13-2006 09:36 AM
For very small numbers or very large numbers, comparing the difference of two floats to a constant can cause problems. I compare the ratios of the two numbers and allow a small tolerance of a variation from 1.0. Reviewing the function help info for the FP_Compare in the Programmer's Toolbox shows that function also looks at a ratio.
Here's a sample more portable than FP_Compare.
#include <ansi_c.h>
#define FP_X_EQ_Y 0
#define FP_X_LT_Y -1
#define FP_X_GT_Y 1
int float_compare(double x, double y);
main()
{
double x, y;
int i, j;
int equals = 0;
int closeenough = 0;
int compared = 0;
// generate some numbers for comparison
for (i=1; i<30; i++)
{
compared++;
x = pow(3.1459, i);
y = 1.0;
for (j=1; j<=i; j++)
y *= 3.1459;
if (x==y)
{
printf("equals\n");
equals++;
}
else
printf("%.10f - %.10f = %.10f\n", x, y, x-y);
if (float_compare(x, y) == FP_X_EQ_Y)
{
printf("close enough\n");
closeenough++;
}
}
// compare a common example of float inequality
x = 0.1;
y = (0.1 - 0.09)/0.1;
compared++;
if (x==y)
{
printf("equals\n");
equals++;
}
else
printf("%.10f - %.10f = %.10f\n", x, y, x-y);
if (float_compare(x, y) == FP_X_EQ_Y)
{
printf("close enough\n");
closeenough++;
}
printf( "%d compared\n"
"%d equal\n"
"%d close enough\n",
compared, equals, closeenough);
}
/******* float_compare ******************
* compares two floating point numbers within a tolerance.
* compares ratios so it will work on small numbers.
* return values are similar to those in strcmp:
* 0 if equal (within the tolerance)
* -1 if x < y
* +1 if x > y
*****************************************/
int float_compare(double x, double y)
{
double float_tolerance = 1e-9;
double ratio;
ratio = x/y;
if (ratio < 1-float_tolerance)
return FP_X_LT_Y;
else if (ratio > 1+float_tolerance)
return FP_X_GT_Y;
else
return FP_X_EQ_Y;
}