What if d1 == DBL_EPSILON and d2 == -LARGE_NUMBER? I think you are
trying to do too much in one routine. I also think I have the
foul-up condition fouled.
I would be very interested to see any instance where this compare
function fails to perform as expected.
C:\tmp>cl /DUNIT_TEST /W4 /Ox fcomp.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
fcomp.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
/out:fcomp.exe
fcomp.obj
C:\tmp>fcomp
compare( 1, 1) = 0.
compare( -1, -1) = 0.
compare( 1, 1) = -1.
compare( 1.84467e+019, 1.84467e+019) = -1.
compare( 2.22045e-016, -1.79769e+308) = 1.
C:\tmp>type fcomp.c
#include <float.h>
#include <math.h>
int double_compare (double d1, double d2)
{
if (d1 > d2)
if ((d1 - d2) < fabs (d1 * DBL_EPSILON))
return 0;
else
return 1;
if (d1 < d2)
if ((d2 - d1) < fabs (d2 * DBL_EPSILON))
return 0;
else
return -1;
return 0;
}
int float_compare (float d1, float d2)
{
if (d1 > d2)
if ((d1 - d2) < fabsf (d1 * FLT_EPSILON))
return 0;
else
return 1;
if (d1 < d2)
if ((d2 - d1) < fabsf (d2 * FLT_EPSILON))
return 0;
else
return -1;
return 0;
}
#ifdef UNIT_TEST
#include <stdio.h>
int main ()
{
double u = 1.0;
double v = u + 1e-14;
double big = 1.0;
double a = 1.0, b = 0.99999999999999999999999999;
printf ("compare(%*g, %*g) = %d.\n", DBL_DIG+2, a, DBL_DIG+2, b,
double_compare (a, b));
a *= -1;
b *= -1;
printf ("compare(%*g, %*g) = %d.\n", DBL_DIG+2, a, DBL_DIG+2, b,
double_compare (a, b));
big *= 1 << 16;
big *= 1 << 16;
big *= 1 << 16;
big *= 1 << 16;
printf ("compare(%*g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
double_compare (u, v));
u *= big;
v *= big;
printf ("compare(%*g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
double_compare (u, v));
u = DBL_EPSILON;
v = -DBL_MAX;
printf ("compare(%*g, %*g) = %d.\n", DBL_DIG+2, u, DBL_DIG+2, v,
double_compare (u, v));
return 0;
}
#endif