Commit 9fe649ea authored by Tom Lane's avatar Tom Lane

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
parent 8597a48d
......@@ -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));
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment