From aa79e331595860489cdbbdce2d5f35a7d1f33783 Mon Sep 17 00:00:00 2001
From: Emre Hasegeli <emre@hasegeli.com>
Date: Wed, 25 May 2016 17:53:19 +0200
Subject: [PATCH] Stop using FP macros on geo_ops.c

---
 src/backend/access/gist/gistproc.c        |  17 +-
 src/backend/access/spgist/spgkdtreeproc.c |  24 +--
 src/backend/utils/adt/geo_ops.c           | 312 +++++++++++++++---------------
 src/backend/utils/adt/geo_spgist.c        |  24 +--
 src/include/utils/geo_decls.h             |  16 --
 src/test/regress/expected/point.out       |   8 +-
 6 files changed, 193 insertions(+), 208 deletions(-)

diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c
index e8213e2..7fb4437 100644
--- a/src/backend/access/gist/gistproc.c
+++ b/src/backend/access/gist/gistproc.c
@@ -1295,44 +1295,41 @@ computeDistance(bool isLeaf, BOX *box, Point *point)
 
 static bool
 gist_point_consistent_internal(StrategyNumber strategy,
 							   bool isLeaf, BOX *key, Point *query)
 {
 	bool		result = false;
 
 	switch (strategy)
 	{
 		case RTLeftStrategyNumber:
-			result = FPlt(key->low.x, query->x);
+			result = key->low.x < query->x;
 			break;
 		case RTRightStrategyNumber:
-			result = FPgt(key->high.x, query->x);
+			result = key->high.x > query->x;
 			break;
 		case RTAboveStrategyNumber:
-			result = FPgt(key->high.y, query->y);
+			result = key->high.y > query->y;
 			break;
 		case RTBelowStrategyNumber:
-			result = FPlt(key->low.y, query->y);
+			result = key->low.y < query->y;
 			break;
 		case RTSameStrategyNumber:
 			if (isLeaf)
 			{
 				/* key.high must equal key.low, so we can disregard it */
-				result = (FPeq(key->low.x, query->x) &&
-						  FPeq(key->low.y, query->y));
+				result = key->low.x == query->x && key->low.y == query->y;
 			}
 			else
 			{
-				result = (FPle(query->x, key->high.x) &&
-						  FPge(query->x, key->low.x) &&
-						  FPle(query->y, key->high.y) &&
-						  FPge(query->y, key->low.y));
+				result = query->x <= key->high.x && query->x >= key->low.x &&
+						 query->y <= key->high.y && query->y >= key->low.y;
 			}
 			break;
 		default:
 			elog(ERROR, "unrecognized strategy number: %d", strategy);
 			result = false;		/* keep compiler quiet */
 			break;
 	}
 
 	return result;
 }
diff --git a/src/backend/access/spgist/spgkdtreeproc.c b/src/backend/access/spgist/spgkdtreeproc.c
index 1ab9335..4b3be5d 100644
--- a/src/backend/access/spgist/spgkdtreeproc.c
+++ b/src/backend/access/spgist/spgkdtreeproc.c
@@ -175,72 +175,72 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS)
 	which = (1 << 1) | (1 << 2);
 
 	for (i = 0; i < in->nkeys; i++)
 	{
 		Point	   *query = DatumGetPointP(in->scankeys[i].sk_argument);
 		BOX		   *boxQuery;
 
 		switch (in->scankeys[i].sk_strategy)
 		{
 			case RTLeftStrategyNumber:
-				if ((in->level % 2) != 0 && FPlt(query->x, coord))
+				if ((in->level % 2) != 0 && query->x < coord)
 					which &= (1 << 1);
 				break;
 			case RTRightStrategyNumber:
-				if ((in->level % 2) != 0 && FPgt(query->x, coord))
+				if ((in->level % 2) != 0 && query->x > coord)
 					which &= (1 << 2);
 				break;
 			case RTSameStrategyNumber:
 				if ((in->level % 2) != 0)
 				{
-					if (FPlt(query->x, coord))
+					if (query->x < coord)
 						which &= (1 << 1);
-					else if (FPgt(query->x, coord))
+					else if (query->x > coord)
 						which &= (1 << 2);
 				}
 				else
 				{
-					if (FPlt(query->y, coord))
+					if (query->y < coord)
 						which &= (1 << 1);
-					else if (FPgt(query->y, coord))
+					else if (query->y > coord)
 						which &= (1 << 2);
 				}
 				break;
 			case RTBelowStrategyNumber:
-				if ((in->level % 2) == 0 && FPlt(query->y, coord))
+				if ((in->level % 2) == 0 && query->y < coord)
 					which &= (1 << 1);
 				break;
 			case RTAboveStrategyNumber:
-				if ((in->level % 2) == 0 && FPgt(query->y, coord))
+				if ((in->level % 2) == 0 && query->y > coord)
 					which &= (1 << 2);
 				break;
 			case RTContainedByStrategyNumber:
 
 				/*
 				 * For this operator, the query is a box not a point.  We
 				 * cheat to the extent of assuming that DatumGetPointP won't
 				 * do anything that would be bad for a pointer-to-box.
 				 */
 				boxQuery = DatumGetBoxP(in->scankeys[i].sk_argument);
 
 				if ((in->level % 2) != 0)
 				{
-					if (FPlt(boxQuery->high.x, coord))
+					if (boxQuery->high.x < coord)
 						which &= (1 << 1);
-					else if (FPgt(boxQuery->low.x, coord))
+					else if (boxQuery->low.x > coord)
 						which &= (1 << 2);
 				}
 				else
 				{
-					if (FPlt(boxQuery->high.y, coord))
+					if (boxQuery->high.y < coord)
 						which &= (1 << 1);
-					else if (FPgt(boxQuery->low.y, coord))
+					else if (boxQuery->low.y > coord)
 						which &= (1 << 2);
 				}
 				break;
 			default:
 				elog(ERROR, "unrecognized strategy number: %d",
 					 in->scankeys[i].sk_strategy);
 				break;
 		}
 
 		if (which == 0)
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 657bcee..7e553e6 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -499,246 +499,246 @@ box_copy(BOX *box)
  *---------------------------------------------------------*/
 
 /*		box_same		-		are two boxes identical?
  */
 Datum
 box_same(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPeq(box1->high.x, box2->high.x) &&
-				   FPeq(box1->low.x, box2->low.x) &&
-				   FPeq(box1->high.y, box2->high.y) &&
-				   FPeq(box1->low.y, box2->low.y));
+	PG_RETURN_BOOL(box1->high.x == box2->high.x &&
+				   box1->low.x == box2->low.x &&
+				   box1->high.y == box2->high.y &&
+				   box1->low.y == box2->low.y);
 }
 
 /*		box_overlap		-		does box1 overlap box2?
  */
 Datum
 box_overlap(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
 	PG_RETURN_BOOL(box_ov(box1, box2));
 }
 
 static bool
 box_ov(BOX *box1, BOX *box2)
 {
-	return (FPle(box1->low.x, box2->high.x) &&
-			FPle(box2->low.x, box1->high.x) &&
-			FPle(box1->low.y, box2->high.y) &&
-			FPle(box2->low.y, box1->high.y));
+	return (box1->low.x <= box2->high.x &&
+			box2->low.x <= box1->high.x &&
+			box1->low.y <= box2->high.y &&
+			box2->low.y <= box1->high.y);
 }
 
 /*		box_left		-		is box1 strictly left of box2?
  */
 Datum
 box_left(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPlt(box1->high.x, box2->low.x));
+	PG_RETURN_BOOL(box1->high.x < box2->low.x);
 }
 
 /*		box_overleft	-		is the right edge of box1 at or left of
  *								the right edge of box2?
  *
  *		This is "less than or equal" for the end of a time range,
  *		when time ranges are stored as rectangles.
  */
 Datum
 box_overleft(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x));
+	PG_RETURN_BOOL(box1->high.x <= box2->high.x);
 }
 
 /*		box_right		-		is box1 strictly right of box2?
  */
 Datum
 box_right(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPgt(box1->low.x, box2->high.x));
+	PG_RETURN_BOOL(box1->low.x > box2->high.x);
 }
 
 /*		box_overright	-		is the left edge of box1 at or right of
  *								the left edge of box2?
  *
  *		This is "greater than or equal" for time ranges, when time ranges
  *		are stored as rectangles.
  */
 Datum
 box_overright(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPge(box1->low.x, box2->low.x));
+	PG_RETURN_BOOL(box1->low.x >= box2->low.x);
 }
 
 /*		box_below		-		is box1 strictly below box2?
  */
 Datum
 box_below(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPlt(box1->high.y, box2->low.y));
+	PG_RETURN_BOOL(box1->high.y < box2->low.y);
 }
 
 /*		box_overbelow	-		is the upper edge of box1 at or below
  *								the upper edge of box2?
  */
 Datum
 box_overbelow(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPle(box1->high.y, box2->high.y));
+	PG_RETURN_BOOL(box1->high.y <= box2->high.y);
 }
 
 /*		box_above		-		is box1 strictly above box2?
  */
 Datum
 box_above(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPgt(box1->low.y, box2->high.y));
+	PG_RETURN_BOOL(box1->low.y > box2->high.y);
 }
 
 /*		box_overabove	-		is the lower edge of box1 at or above
  *								the lower edge of box2?
  */
 Datum
 box_overabove(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPge(box1->low.y, box2->low.y));
+	PG_RETURN_BOOL(box1->low.y >= box2->low.y);
 }
 
 /*		box_contained	-		is box1 contained by box2?
  */
 Datum
 box_contained(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x) &&
-				   FPge(box1->low.x, box2->low.x) &&
-				   FPle(box1->high.y, box2->high.y) &&
-				   FPge(box1->low.y, box2->low.y));
+	PG_RETURN_BOOL(box1->high.x <= box2->high.x &&
+				   box1->low.x >= box2->low.x &&
+				   box1->high.y <= box2->high.y &&
+				   box1->low.y >= box2->low.y);
 }
 
 /*		box_contain		-		does box1 contain box2?
  */
 Datum
 box_contain(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPge(box1->high.x, box2->high.x) &&
-				   FPle(box1->low.x, box2->low.x) &&
-				   FPge(box1->high.y, box2->high.y) &&
-				   FPle(box1->low.y, box2->low.y));
+	PG_RETURN_BOOL(box1->high.x >= box2->high.x &&
+				   box1->low.x <= box2->low.x &&
+				   box1->high.y >= box2->high.y &&
+				   box1->low.y <= box2->low.y);
 }
 
 
 /*		box_positionop	-
  *				is box1 entirely {above,below} box2?
  *
  * box_below_eq and box_above_eq are obsolete versions that (probably
  * erroneously) accept the equal-boundaries case.  Since these are not
  * in sync with the box_left and box_right code, they are deprecated and
  * not supported in the PG 8.1 rtree operator class extension.
  */
 Datum
 box_below_eq(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPle(box1->high.y, box2->low.y));
+	PG_RETURN_BOOL(box1->high.y <= box2->low.y);
 }
 
 Datum
 box_above_eq(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPge(box1->low.y, box2->high.y));
+	PG_RETURN_BOOL(box1->low.y >= box2->high.y);
 }
 
 
 /*		box_relop		-		is area(box1) relop area(box2), within
  *								our accuracy constraint?
  */
 Datum
 box_lt(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPlt(box_ar(box1), box_ar(box2)));
+	PG_RETURN_BOOL(box_ar(box1) < box_ar(box2));
 }
 
 Datum
 box_gt(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPgt(box_ar(box1), box_ar(box2)));
+	PG_RETURN_BOOL(box_ar(box1) > box_ar(box2));
 }
 
 Datum
 box_eq(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPeq(box_ar(box1), box_ar(box2)));
+	PG_RETURN_BOOL(box_ar(box1) == box_ar(box2));
 }
 
 Datum
 box_le(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPle(box_ar(box1), box_ar(box2)));
+	PG_RETURN_BOOL(box_ar(box1) <= box_ar(box2));
 }
 
 Datum
 box_ge(PG_FUNCTION_ARGS)
 {
 	BOX		   *box1 = PG_GETARG_BOX_P(0);
 	BOX		   *box2 = PG_GETARG_BOX_P(1);
 
-	PG_RETURN_BOOL(FPge(box_ar(box1), box_ar(box2)));
+	PG_RETURN_BOOL(box_ar(box1) >= box_ar(box2));
 }
 
 
 /*----------------------------------------------------------
  *	"Arithmetic" operators on boxes.
  *---------------------------------------------------------*/
 
 /*		box_area		-		returns the area of the box.
  */
 Datum
@@ -927,29 +927,29 @@ line_in(PG_FUNCTION_ARGS)
 	s = str;
 	while (isspace((unsigned char) *s))
 		s++;
 	if (*s == '{')
 	{
 		if (!line_decode(s + 1, str, line))
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 					 errmsg("invalid input syntax for type %s: \"%s\"",
 							"line", str)));
-		if (FPzero(line->A) && FPzero(line->B))
+		if (line->A == 0 && line->B == 0)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 					 errmsg("invalid line specification: A and B cannot both be zero")));
 	}
 	else
 	{
 		path_decode(s, true, 2, &(lseg.p[0]), &isopen, NULL, "line", str);
-		if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y))
+		if (lseg.p[0].x == lseg.p[1].x && lseg.p[0].y == lseg.p[1].y)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 					 errmsg("invalid line specification: must be two distinct points")));
 		line_construct_pts(line, &lseg.p[0], &lseg.p[1]);
 	}
 
 	PG_RETURN_LINE_P(line);
 }
 
 
@@ -1029,31 +1029,31 @@ line_construct_pm(Point *pt, double m)
 
 	return result;
 }
 
 /*
  * Fill already-allocated LINE struct from two points on the line
  */
 static void
 line_construct_pts(LINE *line, Point *pt1, Point *pt2)
 {
-	if (FPeq(pt1->x, pt2->x))
+	if (pt1->x == pt2->x)
 	{							/* vertical */
 		/* use "x = C" */
 		line->A = -1;
 		line->B = 0;
 		line->C = pt1->x;
 #ifdef GEODEBUG
 		printf("line_construct_pts- line is vertical\n");
 #endif
 	}
-	else if (FPeq(pt1->y, pt2->y))
+	else if (pt1->y == pt2->y)
 	{							/* horizontal */
 		/* use "y = C" */
 		line->A = 0;
 		line->B = -1;
 		line->C = pt1->y;
 #ifdef GEODEBUG
 		printf("line_construct_pts- line is horizontal\n");
 #endif
 	}
 	else
@@ -1101,75 +1101,77 @@ line_intersect(PG_FUNCTION_ARGS)
 													 LinePGetDatum(l1),
 													 LinePGetDatum(l2))));
 }
 
 Datum
 line_parallel(PG_FUNCTION_ARGS)
 {
 	LINE	   *l1 = PG_GETARG_LINE_P(0);
 	LINE	   *l2 = PG_GETARG_LINE_P(1);
 
-	if (FPzero(l1->B))
-		PG_RETURN_BOOL(FPzero(l2->B));
+	if (l1->B == 0)
+		PG_RETURN_BOOL(l2->B == 0);
 
-	PG_RETURN_BOOL(FPeq(l2->A, l1->A * (l2->B / l1->B)));
+	PG_RETURN_BOOL(l2->A * l1->B == l1->A * l2->B);
 }
 
 Datum
 line_perp(PG_FUNCTION_ARGS)
 {
 	LINE	   *l1 = PG_GETARG_LINE_P(0);
 	LINE	   *l2 = PG_GETARG_LINE_P(1);
 
-	if (FPzero(l1->A))
-		PG_RETURN_BOOL(FPzero(l2->B));
-	else if (FPzero(l1->B))
-		PG_RETURN_BOOL(FPzero(l2->A));
+	if (l1->A == 0)
+		PG_RETURN_BOOL(l2->B == 0);
+	else if (l1->B == 0)
+		PG_RETURN_BOOL(l2->A == 0);
 
-	PG_RETURN_BOOL(FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0));
+	PG_RETURN_BOOL(l1->A * l2->B == l1->B * l2->A * -1.0);
 }
 
 Datum
 line_vertical(PG_FUNCTION_ARGS)
 {
 	LINE	   *line = PG_GETARG_LINE_P(0);
 
-	PG_RETURN_BOOL(FPzero(line->B));
+	PG_RETURN_BOOL(line->B == 0);
 }
 
 Datum
 line_horizontal(PG_FUNCTION_ARGS)
 {
 	LINE	   *line = PG_GETARG_LINE_P(0);
 
-	PG_RETURN_BOOL(FPzero(line->A));
+	PG_RETURN_BOOL(line->A == 0);
 }
 
 Datum
 line_eq(PG_FUNCTION_ARGS)
 {
 	LINE	   *l1 = PG_GETARG_LINE_P(0);
 	LINE	   *l2 = PG_GETARG_LINE_P(1);
 	double		k;
 
-	if (!FPzero(l2->A))
-		k = l1->A / l2->A;
-	else if (!FPzero(l2->B))
-		k = l1->B / l2->B;
-	else if (!FPzero(l2->C))
-		k = l1->C / l2->C;
-	else
-		k = 1.0;
+	if (l1->A == l2->A)
+		PG_RETURN_BOOL(l1->B == l2->B && l1->C == l2->C);
 
-	PG_RETURN_BOOL(FPeq(l1->A, k * l2->A) &&
-				   FPeq(l1->B, k * l2->B) &&
-				   FPeq(l1->C, k * l2->C));
+	if (l1->A != 0)
+		PG_RETURN_BOOL(l1->A * l2->B == l2->A * l1->B &&
+					   l1->A * l2->C == l2->A * l1->C);
+	if (l2->B != 0)
+		PG_RETURN_BOOL(l1->B * l2->A == l2->B * l1->A &&
+					   l1->B * l2->C == l2->B * l1->C);
+	if (l2->C != 0)
+		PG_RETURN_BOOL(l1->C * l2->A == l2->C * l1->A &&
+					   l1->C * l2->B == l2->C * l1->B);
+
+	PG_RETURN_BOOL(false);
 }
 
 
 /*----------------------------------------------------------
  *	Line arithmetic routines.
  *---------------------------------------------------------*/
 
 /* line_distance()
  * Distance between two lines.
  */
@@ -1178,21 +1180,21 @@ line_distance(PG_FUNCTION_ARGS)
 {
 	LINE	   *l1 = PG_GETARG_LINE_P(0);
 	LINE	   *l2 = PG_GETARG_LINE_P(1);
 	float8		result;
 	Point	   *tmp;
 
 	if (!DatumGetBool(DirectFunctionCall2(line_parallel,
 										  LinePGetDatum(l1),
 										  LinePGetDatum(l2))))
 		PG_RETURN_FLOAT8(0.0);
-	if (FPzero(l1->B))			/* vertical? */
+	if (l1->B == 0)			/* vertical? */
 		PG_RETURN_FLOAT8(fabs(l1->C - l2->C));
 	tmp = point_construct(0.0, l1->C);
 	result = dist_pl_internal(tmp, l2);
 	PG_RETURN_FLOAT8(result);
 }
 
 /* line_interpt()
  * Point where two lines l1, l2 intersect (if any)
  */
 Datum
@@ -1224,26 +1226,26 @@ line_interpt_internal(LINE *l1, LINE *l2)
 	/*
 	 * NOTE: if the lines are identical then we will find they are parallel
 	 * and report "no intersection".  This is a little weird, but since
 	 * there's no *unique* intersection, maybe it's appropriate behavior.
 	 */
 	if (DatumGetBool(DirectFunctionCall2(line_parallel,
 										 LinePGetDatum(l1),
 										 LinePGetDatum(l2))))
 		return NULL;
 
-	if (FPzero(l1->B))			/* l1 vertical? */
+	if (l1->B == 0)			/* l1 vertical? */
 	{
 		x = l1->C;
 		y = (l2->A * x + l2->C);
 	}
-	else if (FPzero(l2->B))		/* l2 vertical? */
+	else if (l2->B == 0)		/* l2 vertical? */
 	{
 		x = l2->C;
 		y = (l1->A * x + l1->C);
 	}
 	else
 	{
 		x = (l1->C - l2->C) / (l2->A - l1->A);
 		y = (l1->A * x + l1->C);
 	}
 	result = point_construct(x, y);
@@ -1816,84 +1818,84 @@ point_copy(Point *pt)
  *		that results may, strictly speaking, be a lie (unless
  *		EPSILON = 0.0).
  *---------------------------------------------------------*/
 
 Datum
 point_left(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));
+	PG_RETURN_BOOL(pt1->x < pt2->x);
 }
 
 Datum
 point_right(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));
+	PG_RETURN_BOOL(pt1->x > pt2->x);
 }
 
 Datum
 point_above(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));
+	PG_RETURN_BOOL(pt1->y > pt2->y);
 }
 
 Datum
 point_below(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));
+	PG_RETURN_BOOL(pt1->y < pt2->y);
 }
 
 Datum
 point_vert(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));
+	PG_RETURN_BOOL(pt1->x == pt2->x);
 }
 
 Datum
 point_horiz(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));
+	PG_RETURN_BOOL(pt1->y == pt2->y);
 }
 
 Datum
 point_eq(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
+	PG_RETURN_BOOL(pt1->x == pt2->x && pt1->y == pt2->y);
 }
 
 Datum
 point_ne(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
-	PG_RETURN_BOOL(FPne(pt1->x, pt2->x) || FPne(pt1->y, pt2->y));
+	PG_RETURN_BOOL(pt1->x != pt2->x || pt1->y != pt2->y);
 }
 
 /*----------------------------------------------------------
  *	"Arithmetic" operators on points.
  *---------------------------------------------------------*/
 
 Datum
 point_distance(PG_FUNCTION_ARGS)
 {
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
@@ -1918,21 +1920,21 @@ point_slope(PG_FUNCTION_ARGS)
 	Point	   *pt1 = PG_GETARG_POINT_P(0);
 	Point	   *pt2 = PG_GETARG_POINT_P(1);
 
 	PG_RETURN_FLOAT8(point_sl(pt1, pt2));
 }
 
 
 double
 point_sl(Point *pt1, Point *pt2)
 {
-	return (FPeq(pt1->x, pt2->x)
+	return (pt1->x == pt2->x
 			? (double) DBL_MAX
 			: (pt1->y - pt2->y) / (pt1->x - pt2->x));
 }
 
 
 /***********************************************************************
  **
  **		Routines for 2D line segments.
  **
  ***********************************************************************/
@@ -2072,20 +2074,21 @@ lseg_intersect_internal(LSEG *l1, LSEG *l2)
 		retval = false;
 	return retval;
 }
 
 Datum
 lseg_parallel(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
+	/* The slopes are lossy.  We cannot exact match them. */
 	PG_RETURN_BOOL(FPeq(point_sl(&l1->p[0], &l1->p[1]),
 						point_sl(&l2->p[0], &l2->p[1])));
 }
 
 /* lseg_perp()
  * Determine if two line segments are perpendicular.
  *
  * This code did not get the correct answer for
  *	'((0,0),(0,1))'::lseg ?-| '((0,0),(1,0))'::lseg
  * So, modified it to check explicitly for slope of vertical line
@@ -2099,107 +2102,108 @@ lseg_perp(PG_FUNCTION_ARGS)
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 	double		m1,
 				m2;
 
 	m1 = point_sl(&(l1->p[0]), &(l1->p[1]));
 	m2 = point_sl(&(l2->p[0]), &(l2->p[1]));
 
 #ifdef GEODEBUG
 	printf("lseg_perp- slopes are %g and %g\n", m1, m2);
 #endif
-	if (FPzero(m1))
-		PG_RETURN_BOOL(FPeq(m2, DBL_MAX));
-	else if (FPzero(m2))
-		PG_RETURN_BOOL(FPeq(m1, DBL_MAX));
+	if (m1 == 0)
+		PG_RETURN_BOOL(m2 == DBL_MAX);
+	else if (m2 == 0)
+		PG_RETURN_BOOL(m1 == DBL_MAX);
 
-	PG_RETURN_BOOL(FPeq(m1 / m2, -1.0));
+	/* The slopes are lossy.  We cannot exact match them. */
+	PG_RETURN_BOOL(FPeq(m1, m2 * -1.0));
 }
 
 Datum
 lseg_vertical(PG_FUNCTION_ARGS)
 {
 	LSEG	   *lseg = PG_GETARG_LSEG_P(0);
 
-	PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));
+	PG_RETURN_BOOL(lseg->p[0].x == lseg->p[1].x);
 }
 
 Datum
 lseg_horizontal(PG_FUNCTION_ARGS)
 {
 	LSEG	   *lseg = PG_GETARG_LSEG_P(0);
 
-	PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));
+	PG_RETURN_BOOL(lseg->p[0].y == lseg->p[1].y);
 }
 
 
 Datum
 lseg_eq(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(FPeq(l1->p[0].x, l2->p[0].x) &&
-				   FPeq(l1->p[0].y, l2->p[0].y) &&
-				   FPeq(l1->p[1].x, l2->p[1].x) &&
-				   FPeq(l1->p[1].y, l2->p[1].y));
+	PG_RETURN_BOOL(l1->p[0].x == l2->p[0].x &&
+				   l1->p[0].y == l2->p[0].y &&
+				   l1->p[1].x == l2->p[1].x &&
+				   l1->p[1].y == l2->p[1].y);
 }
 
 Datum
 lseg_ne(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(!FPeq(l1->p[0].x, l2->p[0].x) ||
-				   !FPeq(l1->p[0].y, l2->p[0].y) ||
-				   !FPeq(l1->p[1].x, l2->p[1].x) ||
-				   !FPeq(l1->p[1].y, l2->p[1].y));
+	PG_RETURN_BOOL(l1->p[0].x != l2->p[0].x ||
+				   l1->p[0].y != l2->p[0].y ||
+				   l1->p[1].x != l2->p[1].x ||
+				   l1->p[1].y != l2->p[1].y);
 }
 
 Datum
 lseg_lt(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]),
-						point_dt(&l2->p[0], &l2->p[1])));
+	PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) <
+				   point_dt(&l2->p[0], &l2->p[1]));
 }
 
 Datum
 lseg_le(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1]),
-						point_dt(&l2->p[0], &l2->p[1])));
+	PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) <=
+				   point_dt(&l2->p[0], &l2->p[1]));
 }
 
 Datum
 lseg_gt(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]),
-						point_dt(&l2->p[0], &l2->p[1])));
+	PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) >
+				   point_dt(&l2->p[0], &l2->p[1]));
 }
 
 Datum
 lseg_ge(PG_FUNCTION_ARGS)
 {
 	LSEG	   *l1 = PG_GETARG_LSEG_P(0);
 	LSEG	   *l2 = PG_GETARG_LSEG_P(1);
 
-	PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1]),
-						point_dt(&l2->p[0], &l2->p[1])));
+	PG_RETURN_BOOL(point_dt(&l1->p[0], &l1->p[1]) >=
+				   point_dt(&l2->p[0], &l2->p[1]));
 }
 
 
 /*----------------------------------------------------------
  *	Line arithmetic routines.
  *---------------------------------------------------------*/
 
 /* lseg_distance -
  *		If two segments don't intersect, then the closest
  *		point will be from one of the endpoints to the other
@@ -2278,21 +2282,22 @@ lseg_interpt_internal(LSEG *l1, LSEG *l2)
 	if (!on_ps_internal(result, l1) ||
 		!on_ps_internal(result, l2))
 	{
 		pfree(result);
 		return NULL;
 	}
 
 	/*
 	 * If there is an intersection, then check explicitly for matching
 	 * endpoints since there may be rounding effects with annoying lsb
-	 * residue. - tgl 1997-07-09
+	 * residue.  We are fuzzy matching them to be compatible with
+	 * on_ps_internal().
 	 */
 	if ((FPeq(l1->p[0].x, l2->p[0].x) && FPeq(l1->p[0].y, l2->p[0].y)) ||
 		(FPeq(l1->p[0].x, l2->p[1].x) && FPeq(l1->p[0].y, l2->p[1].y)))
 	{
 		result->x = l1->p[0].x;
 		result->y = l1->p[0].y;
 	}
 	else if ((FPeq(l1->p[1].x, l2->p[0].x) && FPeq(l1->p[1].y, l2->p[0].y)) ||
 			 (FPeq(l1->p[1].x, l2->p[1].x) && FPeq(l1->p[1].y, l2->p[1].y)))
 	{
@@ -2714,27 +2719,27 @@ Datum
 close_pl(PG_FUNCTION_ARGS)
 {
 	Point	   *pt = PG_GETARG_POINT_P(0);
 	LINE	   *line = PG_GETARG_LINE_P(1);
 	Point	   *result;
 	LINE	   *tmp;
 	double		invm;
 
 	result = (Point *) palloc(sizeof(Point));
 
-	if (FPzero(line->B))		/* vertical? */
+	if (line->B == 0)		/* vertical? */
 	{
 		result->x = line->C;
 		result->y = pt->y;
 		PG_RETURN_POINT_P(result);
 	}
-	if (FPzero(line->A))		/* horizontal? */
+	if (line->A == 0)		/* horizontal? */
 	{
 		result->x = pt->x;
 		result->y = line->C;
 		PG_RETURN_POINT_P(result);
 	}
 	/* drop a perpendicular and find the intersection point */
 
 	/* invert and flip the sign on the slope to get a perpendicular */
 	invm = line->B / line->A;
 	tmp = line_construct_pm(pt, invm);
@@ -2759,51 +2764,51 @@ close_ps(PG_FUNCTION_ARGS)
 {
 	Point	   *pt = PG_GETARG_POINT_P(0);
 	LSEG	   *lseg = PG_GETARG_LSEG_P(1);
 	Point	   *result = NULL;
 	LINE	   *tmp;
 	double		invm;
 	int			xh,
 				yh;
 
 #ifdef GEODEBUG
-	printf("close_sp:pt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f  lseg(1).x %f lseg(1).y %f\n",
+	printf("close_ps:spt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f  lseg(1).x %f lseg(1).y %f\n",
 		   pt->x, pt->y, lseg->p[0].x, lseg->p[0].y,
 		   lseg->p[1].x, lseg->p[1].y);
 #endif
 
 	/* xh (or yh) is the index of upper x( or y) end point of lseg */
 	/* !xh (or !yh) is the index of lower x( or y) end point of lseg */
 	xh = lseg->p[0].x < lseg->p[1].x;
 	yh = lseg->p[0].y < lseg->p[1].y;
 
-	if (FPeq(lseg->p[0].x, lseg->p[1].x))		/* vertical? */
+	if (lseg->p[0].x == lseg->p[1].x)		/* vertical? */
 	{
 #ifdef GEODEBUG
 		printf("close_ps- segment is vertical\n");
 #endif
 		/* first check if point is below or above the entire lseg. */
 		if (pt->y < lseg->p[!yh].y)
 			result = point_copy(&lseg->p[!yh]); /* below the lseg */
 		else if (pt->y > lseg->p[yh].y)
 			result = point_copy(&lseg->p[yh]);	/* above the lseg */
 		if (result != NULL)
 			PG_RETURN_POINT_P(result);
 
 		/* point lines along (to left or right) of the vertical lseg. */
 
 		result = (Point *) palloc(sizeof(Point));
 		result->x = lseg->p[0].x;
 		result->y = pt->y;
 		PG_RETURN_POINT_P(result);
 	}
-	else if (FPeq(lseg->p[0].y, lseg->p[1].y))	/* horizontal? */
+	else if (lseg->p[0].y == lseg->p[1].y)	/* horizontal? */
 	{
 #ifdef GEODEBUG
 		printf("close_ps- segment is horizontal\n");
 #endif
 		/* first check if point is left or right of the entire lseg. */
 		if (pt->x < lseg->p[!xh].x)
 			result = point_copy(&lseg->p[!xh]); /* left of the lseg */
 		else if (pt->x > lseg->p[xh].x)
 			result = point_copy(&lseg->p[xh]);	/* right of the lseg */
 		if (result != NULL)
@@ -3118,40 +3123,41 @@ close_lb(PG_FUNCTION_ARGS)
 
 /* on_pl -
  *		Does the point satisfy the equation?
  */
 Datum
 on_pl(PG_FUNCTION_ARGS)
 {
 	Point	   *pt = PG_GETARG_POINT_P(0);
 	LINE	   *line = PG_GETARG_LINE_P(1);
 
-	PG_RETURN_BOOL(FPzero(line->A * pt->x + line->B * pt->y + line->C));
+	PG_RETURN_BOOL(line->A * pt->x + line->B * pt->y + line->C == 0);
 }
 
 
 /* on_ps -
- *		Determine colinearity by detecting a triangle inequality.
+ *		Determine collinearity by detecting a triangle inequality.
  * This algorithm seems to behave nicely even with lsb residues - tgl 1997-07-09
  */
 Datum
 on_ps(PG_FUNCTION_ARGS)
 {
 	Point	   *pt = PG_GETARG_POINT_P(0);
 	LSEG	   *lseg = PG_GETARG_LSEG_P(1);
 
 	PG_RETURN_BOOL(on_ps_internal(pt, lseg));
 }
 
 static bool
 on_ps_internal(Point *pt, LSEG *lseg)
 {
+	/* The distances are lossy.  We cannot exact match them. */
 	return FPeq(point_dt(pt, &lseg->p[0]) + point_dt(pt, &lseg->p[1]),
 				point_dt(&lseg->p[0], &lseg->p[1]));
 }
 
 Datum
 on_pb(PG_FUNCTION_ARGS)
 {
 	Point	   *pt = PG_GETARG_POINT_P(0);
 	BOX		   *box = PG_GETARG_BOX_P(1);
 
@@ -3191,22 +3197,21 @@ on_ppath(PG_FUNCTION_ARGS)
 				b;
 
 	/*-- OPEN --*/
 	if (!path->closed)
 	{
 		n = path->npts - 1;
 		a = point_dt(pt, &path->p[0]);
 		for (i = 0; i < n; i++)
 		{
 			b = point_dt(pt, &path->p[i + 1]);
-			if (FPeq(a + b,
-					 point_dt(&path->p[i], &path->p[i + 1])))
+			if (a + b == point_dt(&path->p[i], &path->p[i + 1]))
 				PG_RETURN_BOOL(true);
 			a = b;
 		}
 		PG_RETURN_BOOL(false);
 	}
 
 	/*-- CLOSED --*/
 	PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
 }
 
@@ -3810,21 +3815,21 @@ poly_overlap(PG_FUNCTION_ARGS)
 
 static bool
 touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
 {
 	/* point a is on s, b is not */
 	LSEG		t;
 
 	t.p[0] = *a;
 	t.p[1] = *b;
 
-#define POINTEQ(pt1, pt2)	(FPeq((pt1)->x, (pt2)->x) && FPeq((pt1)->y, (pt2)->y))
+#define POINTEQ(pt1, pt2)	((pt1)->x == (pt2)->x && (pt1)->y == (pt2)->y)
 	if (POINTEQ(a, s->p))
 	{
 		if (on_ps_internal(s->p + 1, &t))
 			return lseg_inside_poly(b, s->p + 1, poly, start);
 	}
 	else if (POINTEQ(a, s->p + 1))
 	{
 		if (on_ps_internal(s->p, &t))
 			return lseg_inside_poly(b, s->p, poly, start);
 	}
@@ -4648,216 +4653,218 @@ circle_send(PG_FUNCTION_ARGS)
  *---------------------------------------------------------*/
 
 /*		circles identical?
  */
 Datum
 circle_same(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPeq(circle1->radius, circle2->radius) &&
-				   FPeq(circle1->center.x, circle2->center.x) &&
-				   FPeq(circle1->center.y, circle2->center.y));
+	PG_RETURN_BOOL(circle1->radius == circle2->radius &&
+				   circle1->center.x == circle2->center.x &&
+				   circle1->center.y == circle2->center.y);
 }
 
 /*		circle_overlap	-		does circle1 overlap circle2?
  */
 Datum
 circle_overlap(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center),
-						circle1->radius + circle2->radius));
+	PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) <=
+				   circle1->radius + circle2->radius);
 }
 
 /*		circle_overleft -		is the right edge of circle1 at or left of
  *								the right edge of circle2?
  */
 Datum
 circle_overleft(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle((circle1->center.x + circle1->radius),
-						(circle2->center.x + circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.x + circle1->radius <=
+				   circle2->center.x + circle2->radius);
 }
 
 /*		circle_left		-		is circle1 strictly left of circle2?
  */
 Datum
 circle_left(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPlt((circle1->center.x + circle1->radius),
-						(circle2->center.x - circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.x + circle1->radius <
+				   circle2->center.x - circle2->radius);
 }
 
 /*		circle_right	-		is circle1 strictly right of circle2?
  */
 Datum
 circle_right(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPgt((circle1->center.x - circle1->radius),
-						(circle2->center.x + circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.x - circle1->radius >
+				   circle2->center.x + circle2->radius);
 }
 
 /*		circle_overright	-	is the left edge of circle1 at or right of
  *								the left edge of circle2?
  */
 Datum
 circle_overright(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPge((circle1->center.x - circle1->radius),
-						(circle2->center.x - circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.x - circle1->radius >=
+				   circle2->center.x - circle2->radius);
 }
 
 /*		circle_contained		-		is circle1 contained by circle2?
  */
 Datum
 circle_contained(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle1->radius), circle2->radius));
+	PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) +
+				   circle1->radius <= circle2->radius);
 }
 
 /*		circle_contain	-		does circle1 contain circle2?
  */
 Datum
 circle_contain(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle2->radius), circle1->radius));
+	PG_RETURN_BOOL(point_dt(&circle1->center, &circle2->center) +
+				   circle2->radius <= circle1->radius);
 }
 
 
 /*		circle_below		-		is circle1 strictly below circle2?
  */
 Datum
 circle_below(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPlt((circle1->center.y + circle1->radius),
-						(circle2->center.y - circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.y + circle1->radius <
+				   circle2->center.y - circle2->radius);
 }
 
 /*		circle_above	-		is circle1 strictly above circle2?
  */
 Datum
 circle_above(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPgt((circle1->center.y - circle1->radius),
-						(circle2->center.y + circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.y - circle1->radius >
+				   circle2->center.y + circle2->radius);
 }
 
 /*		circle_overbelow -		is the upper edge of circle1 at or below
  *								the upper edge of circle2?
  */
 Datum
 circle_overbelow(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle((circle1->center.y + circle1->radius),
-						(circle2->center.y + circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.y + circle1->radius <=
+				   circle2->center.y + circle2->radius);
 }
 
 /*		circle_overabove	-	is the lower edge of circle1 at or above
  *								the lower edge of circle2?
  */
 Datum
 circle_overabove(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPge((circle1->center.y - circle1->radius),
-						(circle2->center.y - circle2->radius)));
+	PG_RETURN_BOOL(circle1->center.y - circle1->radius >=
+				   circle2->center.y - circle2->radius);
 }
 
 
 /*		circle_relop	-		is area(circle1) relop area(circle2), within
  *								our accuracy constraint?
  */
 Datum
 circle_eq(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPeq(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) == circle_ar(circle2));
 }
 
 Datum
 circle_ne(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPne(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) != circle_ar(circle2));
 }
 
 Datum
 circle_lt(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPlt(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) < circle_ar(circle2));
 }
 
 Datum
 circle_gt(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPgt(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) > circle_ar(circle2));
 }
 
 Datum
 circle_le(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPle(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) <= circle_ar(circle2));
 }
 
 Datum
 circle_ge(PG_FUNCTION_ARGS)
 {
 	CIRCLE	   *circle1 = PG_GETARG_CIRCLE_P(0);
 	CIRCLE	   *circle2 = PG_GETARG_CIRCLE_P(1);
 
-	PG_RETURN_BOOL(FPge(circle_ar(circle1), circle_ar(circle2)));
+	PG_RETURN_BOOL(circle_ar(circle1) >= circle_ar(circle2));
 }
 
 
 /*----------------------------------------------------------
  *	"Arithmetic" operators on circles.
  *---------------------------------------------------------*/
 
 static CIRCLE *
 circle_copy(CIRCLE *circle)
 {
@@ -5146,21 +5153,21 @@ circle_poly(PG_FUNCTION_ARGS)
 {
 	int32		npts = PG_GETARG_INT32(0);
 	CIRCLE	   *circle = PG_GETARG_CIRCLE_P(1);
 	POLYGON    *poly;
 	int			base_size,
 				size;
 	int			i;
 	double		angle;
 	double		anglestep;
 
-	if (FPzero(circle->radius))
+	if (circle->radius == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 			   errmsg("cannot convert circle with radius zero to polygon")));
 
 	if (npts < 2)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("must request at least 2 points")));
 
 	base_size = sizeof(poly->p[0]) * npts;
@@ -5305,110 +5312,107 @@ point_inside(Point *p, int npts, Point *plist)
  * Wow, that is one confusing API, but it is used above, and when summed,
  * can tell is if a point is in a polygon.
  */
 
 static int
 lseg_crossing(double x, double y, double prev_x, double prev_y)
 {
 	double		z;
 	int			y_sign;
 
-	if (FPzero(y))
+	if (y == 0)
 	{							/* y == 0, on X axis */
-		if (FPzero(x))			/* (x,y) is (0,0)? */
+		if (x == 0)			/* (x,y) is (0,0)? */
 			return POINT_ON_POLYGON;
-		else if (FPgt(x, 0))
+		else if (x > 0)
 		{						/* x > 0 */
-			if (FPzero(prev_y)) /* y and prev_y are zero */
+			if (prev_y == 0) /* y and prev_y are zero */
 				/* prev_x > 0? */
-				return FPgt(prev_x, 0) ? 0 : POINT_ON_POLYGON;
-			return FPlt(prev_y, 0) ? 1 : -1;
+				return prev_x > 0 ? 0 : POINT_ON_POLYGON;
+			return prev_y < 0 ? 1 : -1;
 		}
 		else
 		{						/* x < 0, x not on positive X axis */
-			if (FPzero(prev_y))
+			if (prev_y == 0)
 				/* prev_x < 0? */
-				return FPlt(prev_x, 0) ? 0 : POINT_ON_POLYGON;
+				return prev_x < 0 ? 0 : POINT_ON_POLYGON;
 			return 0;
 		}
 	}
 	else
 	{							/* y != 0 */
 		/* compute y crossing direction from previous point */
-		y_sign = FPgt(y, 0) ? 1 : -1;
+		y_sign = y > 0 ? 1 : -1;
 
-		if (FPzero(prev_y))
+		if (prev_y == 0)
 			/* previous point was on X axis, so new point is either off or on */
-			return FPlt(prev_x, 0) ? 0 : y_sign;
-		else if (FPgt(y_sign * prev_y, 0))
+			return prev_x < 0 ? 0 : y_sign;
+		else if (y_sign * prev_y > 0)
 			/* both above or below X axis */
 			return 0;			/* same sign */
 		else
 		{						/* y and prev_y cross X-axis */
-			if (FPge(x, 0) && FPgt(prev_x, 0))
+			if (x >= 0 && prev_x > 0)
 				/* both non-negative so cross positive X-axis */
 				return 2 * y_sign;
-			if (FPlt(x, 0) && FPle(prev_x, 0))
+			if (x < 0 && prev_x <= 0)
 				/* both non-positive so do not cross positive X-axis */
 				return 0;
 
 			/* x and y cross axises, see URL above point_inside() */
 			z = (x - prev_x) * y - (y - prev_y) * x;
-			if (FPzero(z))
+			if (z == 0)
 				return POINT_ON_POLYGON;
-			return FPgt((y_sign * z), 0) ? 0 : 2 * y_sign;
+			return y_sign * z > 0 ? 0 : 2 * y_sign;
 		}
 	}
 }
 
 
 static bool
 plist_same(int npts, Point *p1, Point *p2)
 {
 	int			i,
 				ii,
 				j;
 
 	/* find match for first point */
 	for (i = 0; i < npts; i++)
 	{
-		if ((FPeq(p2[i].x, p1[0].x))
-			&& (FPeq(p2[i].y, p1[0].y)))
+		if (p2[i].x == p1[0].x && p2[i].y == p1[0].y)
 		{
 
 			/* match found? then look forward through remaining points */
 			for (ii = 1, j = i + 1; ii < npts; ii++, j++)
 			{
 				if (j >= npts)
 					j = 0;
-				if ((!FPeq(p2[j].x, p1[ii].x))
-					|| (!FPeq(p2[j].y, p1[ii].y)))
+				if (p2[j].x != p1[ii].x || p2[j].y != p1[ii].y)
 				{
 #ifdef GEODEBUG
 					printf("plist_same- %d failed forward match with %d\n", j, ii);
 #endif
 					break;
 				}
 			}
 #ifdef GEODEBUG
 			printf("plist_same- ii = %d/%d after forward match\n", ii, npts);
 #endif
 			if (ii == npts)
 				return TRUE;
 
 			/* match not found forwards? then look backwards */
 			for (ii = 1, j = i - 1; ii < npts; ii++, j--)
 			{
 				if (j < 0)
 					j = (npts - 1);
-				if ((!FPeq(p2[j].x, p1[ii].x))
-					|| (!FPeq(p2[j].y, p1[ii].y)))
+				if (p2[j].x != p1[ii].x || p2[j].y != p1[ii].y)
 				{
 #ifdef GEODEBUG
 					printf("plist_same- %d failed reverse match with %d\n", j, ii);
 #endif
 					break;
 				}
 			}
 #ifdef GEODEBUG
 			printf("plist_same- ii = %d/%d after reverse match\n", ii, npts);
 #endif
diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c
index 83d509e..4b82f89 100644
--- a/src/backend/utils/adt/geo_spgist.c
+++ b/src/backend/utils/adt/geo_spgist.c
@@ -225,80 +225,80 @@ nextRectBox(RectBox *rect_box, RangeBox *centroid, uint8 quadrant)
 	else
 		next_rect_box->range_box_y.right.high = centroid->right.high;
 
 	return next_rect_box;
 }
 
 /* Can any range from range_box overlap with this argument? */
 static bool
 overlap2D(RangeBox *range_box, Range *query)
 {
-	return FPge(range_box->right.high, query->low) &&
-		   FPle(range_box->left.low, query->high);
+	return range_box->right.high >= query->low &&
+		   range_box->left.low <= query->high;
 }
 
 /* Can any rectangle from rect_box overlap with this argument? */
 static bool
 overlap4D(RectBox *rect_box, RangeBox *query)
 {
 	return overlap2D(&rect_box->range_box_x, &query->left) &&
 		   overlap2D(&rect_box->range_box_y, &query->right);
 }
 
 /* Can any range from range_box contain this argument? */
 static bool
 contain2D(RangeBox *range_box, Range *query)
 {
-	return FPge(range_box->right.high, query->high) &&
-		   FPle(range_box->left.low, query->low);
+	return range_box->right.high >= query->high &&
+		   range_box->left.low <= query->low;
 }
 
 /* Can any rectangle from rect_box contain this argument? */
 static bool
 contain4D(RectBox *rect_box, RangeBox * query)
 {
 	return contain2D(&rect_box->range_box_x, &query->left) &&
 		   contain2D(&rect_box->range_box_y, &query->right);
 }
 
 /* Can any range from range_box be contained by this argument? */
 static bool
 contained2D(RangeBox *range_box, Range *query)
 {
-	return FPle(range_box->left.low, query->high) &&
-		   FPge(range_box->left.high, query->low) &&
-		   FPle(range_box->right.low, query->high) &&
-		   FPge(range_box->right.high, query->low);
+	return range_box->left.low <= query->high &&
+		   range_box->left.high >= query->low &&
+		   range_box->right.low <= query->high &&
+		   range_box->right.high >= query->low;
 }
 
 /* Can any rectangle from rect_box be contained by this argument? */
 static bool
 contained4D(RectBox *rect_box, RangeBox *query)
 {
 	return contained2D(&rect_box->range_box_x, &query->left) &&
 		   contained2D(&rect_box->range_box_y, &query->right);
 }
 
 /* Can any range from range_box to be lower than this argument? */
 static bool
 lower2D(RangeBox *range_box, Range *query)
 {
-	return FPlt(range_box->left.low, query->low) &&
-		   FPlt(range_box->right.low, query->low);
+	return range_box->left.low < query->low &&
+		   range_box->right.low < query->low;
 }
 
 /* Can any range from range_box to be higher than this argument? */
 static bool
 higher2D(RangeBox *range_box, Range *query)
 {
-	return FPgt(range_box->left.high, query->high) &&
-		   FPgt(range_box->right.high, query->high);
+	return range_box->left.high > query->high &&
+		   range_box->right.high > query->high;
 }
 
 /* Can any rectangle from rect_box be left of this argument? */
 static bool
 left4D(RectBox *rect_box, RangeBox *query)
 {
 	return lower2D(&rect_box->range_box_x, &query->left);
 }
 
 /* Can any rectangle from rect_box does not extend the right of this argument? */
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index acf3202..163bc57 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -25,37 +25,21 @@
 
 #include "fmgr.h"
 
 /*--------------------------------------------------------------------
  * Useful floating point utilities and constants.
  *-------------------------------------------------------------------*/
 
 
 #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
 
 #define HYPOT(A, B)				pg_hypot(A, B)
 
 /*---------------------------------------------------------------------
  * Point - (x,y)
  *-------------------------------------------------------------------*/
 typedef struct
 {
 	double		x,
 				y;
diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out
index bfc0962..6319652 100644
--- a/src/test/regress/expected/point.out
+++ b/src/test/regress/expected/point.out
@@ -249,49 +249,49 @@ SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS dista
 CREATE TEMP TABLE point_gist_tbl(f1 point);
 INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000);
 CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1);
 INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)');
 SET enable_seqscan TO true;
 SET enable_indexscan TO false;
 SET enable_bitmapscan TO false;
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point;
  count 
 -------
-  1002
+     1
 (1 row)
 
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box;
  count 
 -------
      1
 (1 row)
 
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point;
  count 
 -------
-     1
+     0
 (1 row)
 
 SET enable_seqscan TO false;
 SET enable_indexscan TO true;
 SET enable_bitmapscan TO true;
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point;
  count 
 -------
-  1002
+     1
 (1 row)
 
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box;
  count 
 -------
      1
 (1 row)
 
 SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point;
  count 
 -------
-     1
+     0
 (1 row)
 
 RESET enable_seqscan;
 RESET enable_indexscan;
 RESET enable_bitmapscan;
-- 
2.7.4 (Apple Git-66)

