aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/geo_ops.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-11-21 17:24:07 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2020-11-21 17:24:07 -0500
commit9fe649ea295f00baf6d0f0c1f9b0cb1298f64fb9 (patch)
treeac2742cd9c375dd25b9a5ba973daa50c39cde1e2 /src/backend/utils/adt/geo_ops.c
parent8597a48d01b6cc0b09ff626253ac93c67e5516d5 (diff)
downloadpostgresql-9fe649ea295f00baf6d0f0c1f9b0cb1298f64fb9.tar.gz
postgresql-9fe649ea295f00baf6d0f0c1f9b0cb1298f64fb9.zip
In geo_ops.c, represent infinite slope as Infinity, not DBL_MAX.
Since we're assuming IEEE floats these days, there seems little reason not to do this. It has the advantage that when the slope is computed as infinite due to the presence of Inf coordinates, we get saner behavior than before from line_construct(), and thence also in some dependent operations such as finding the closest point. Also fix line_construct() to special-case slope zero. The previous coding got the right answer in most cases, but it could compute C as NaN when the point has Inf coordinates. Discussion: https://postgr.es/m/CAGf+fX70rWFOk5cd00uMfa__0yP+vtQg5ck7c2Onb-Yczp0URA@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/geo_ops.c')
-rw-r--r--src/backend/utils/adt/geo_ops.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 82286ef87a3..c1dc511a1a8 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -1055,13 +1055,20 @@ line_send(PG_FUNCTION_ARGS)
static inline void
line_construct(LINE *result, Point *pt, float8 m)
{
- if (m == DBL_MAX)
+ if (isinf(m))
{
/* vertical - use "x = C" */
result->A = -1.0;
result->B = 0.0;
result->C = pt->x;
}
+ else if (m == 0)
+ {
+ /* horizontal - use "y = C" */
+ result->A = 0.0;
+ result->B = -1.0;
+ result->C = pt->y;
+ }
else
{
/* use "mx - y + yinter = 0" */
@@ -1201,7 +1208,7 @@ line_sl(LINE *line)
if (FPzero(line->A))
return 0.0;
if (FPzero(line->B))
- return DBL_MAX;
+ return get_float8_infinity();
return float8_div(line->A, -line->B);
}
@@ -1213,7 +1220,7 @@ static inline float8
line_invsl(LINE *line)
{
if (FPzero(line->A))
- return DBL_MAX;
+ return get_float8_infinity();
if (FPzero(line->B))
return 0.0;
return float8_div(line->B, line->A);
@@ -1979,13 +1986,13 @@ point_slope(PG_FUNCTION_ARGS)
/*
* Return slope of two points
*
- * Note that this function returns DBL_MAX when the points are the same.
+ * Note that this function returns Inf when the points are the same.
*/
static inline float8
point_sl(Point *pt1, Point *pt2)
{
if (FPeq(pt1->x, pt2->x))
- return DBL_MAX;
+ return get_float8_infinity();
if (FPeq(pt1->y, pt2->y))
return 0.0;
return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x));
@@ -2003,7 +2010,7 @@ point_invsl(Point *pt1, Point *pt2)
if (FPeq(pt1->x, pt2->x))
return 0.0;
if (FPeq(pt1->y, pt2->y))
- return DBL_MAX;
+ return get_float8_infinity();
return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y));
}