| From: | "Dann Corbit" <DCorbit(at)connx(dot)com> |
|---|---|
| To: | "Hackers List" <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | geo_decls.h oopsie... |
| Date: | 2002-02-14 00:26:34 |
| Message-ID: | D90A5A6C612A39408103E6ECDD77B8290FD4E3@voyager.corporate.connx.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
These macros are from geo_decls.h:
#define EPSILON 1.0E-06
#ifdef EPSILON
#define FPzero(A) (fabs(A) <= EPSILON)
#define FPeq(A,B) (fabs((A) - (B)) <=
EPSILON)
#define FPne(A,B) (fabs((A) - (B)) >
EPSILON)
#define FPlt(A,B) ((B) - (A) > EPSILON)
#define FPle(A,B) ((A) - (B) <= EPSILON)
#define FPgt(A,B) ((A) - (B) > EPSILON)
#define FPge(A,B) ((B) - (A) <= EPSILON)
#else
#define FPzero(A) ((A) == 0)
#define FPeq(A,B) ((A) == (B))
#define FPne(A,B) ((A) != (B))
#define FPlt(A,B) ((A) < (B))
#define FPle(A,B) ((A) <= (B))
#define FPgt(A,B) ((A) > (B))
#define FPge(A,B) ((A) >= (B))
#endif
But to compare floating point, those are simply wrong. If the values
are both very small or both very large, the method fails.
Here is a more reliable way to make a comparison:
#include <float.h>
double 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;
}
float float_compare(float d1, float d2)
{
if (d1 > d2)
if ((d1 - d2) < fabs(d1 * FLT_EPSILON))
return 0;
else
return 1;
if (d1 < d2)
if ((d2 - d1) < fabs(d2 * FLT_EPSILON))
return 0;
else
return -1;
return 0;
}
All the macros can then be defined in terms of the comparison function.
It's not perfect either, but at least it is better.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dann Corbit | 2002-02-14 00:28:38 | Re: geo_decls.h oopsie... |
| Previous Message | Peter Eisentraut | 2002-02-14 00:26:22 | Re: When and where to check for function permissions |