From 9fe649ea295f00baf6d0f0c1f9b0cb1298f64fb9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 21 Nov 2020 17:24:07 -0500 Subject: 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 --- src/backend/utils/adt/geo_ops.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/backend/utils/adt/geo_ops.c') 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)); } -- cgit v1.2.3