diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-21 17:24:07 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-21 17:24:07 -0500 |
commit | 9fe649ea295f00baf6d0f0c1f9b0cb1298f64fb9 (patch) | |
tree | ac2742cd9c375dd25b9a5ba973daa50c39cde1e2 /src/backend/utils/adt/geo_ops.c | |
parent | 8597a48d01b6cc0b09ff626253ac93c67e5516d5 (diff) | |
download | postgresql-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.c | 19 |
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)); } |