mirror of
https://github.com/postgres/postgres.git
synced 2025-11-28 11:44:57 +03:00
Replace internal C function pg_hypot() by standard hypot()
The code comment said, "It is expected that this routine will eventually be replaced with the C99 hypot() function.", so let's do that now. This function is tested via the geometry regression test, so if it is faulty on any platform, it will show up there. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/170308e6-a7a3-4484-87b2-f960bb564afa%40eisentraut.org
This commit is contained in:
@@ -51,7 +51,7 @@ point_box_distance(Point *point, BOX *box)
|
||||
else
|
||||
dy = 0.0;
|
||||
|
||||
return HYPOT(dx, dy);
|
||||
return hypot(dx, dy);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1276,7 +1276,7 @@ line_distance(PG_FUNCTION_ARGS)
|
||||
|
||||
PG_RETURN_FLOAT8(float8_div(fabs(float8_mi(l1->C,
|
||||
float8_mul(ratio, l2->C))),
|
||||
HYPOT(l1->A, l1->B)));
|
||||
hypot(l1->A, l1->B)));
|
||||
}
|
||||
|
||||
/* line_interpt()
|
||||
@@ -2001,7 +2001,7 @@ point_distance(PG_FUNCTION_ARGS)
|
||||
static inline float8
|
||||
point_dt(Point *pt1, Point *pt2)
|
||||
{
|
||||
return HYPOT(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y));
|
||||
return hypot(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y));
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -5005,7 +5005,7 @@ circle_mul_pt(PG_FUNCTION_ARGS)
|
||||
result = (CIRCLE *) palloc(sizeof(CIRCLE));
|
||||
|
||||
point_mul_point(&result->center, &circle->center, point);
|
||||
result->radius = float8_mul(circle->radius, HYPOT(point->x, point->y));
|
||||
result->radius = float8_mul(circle->radius, hypot(point->x, point->y));
|
||||
|
||||
PG_RETURN_CIRCLE_P(result);
|
||||
}
|
||||
@@ -5020,7 +5020,7 @@ circle_div_pt(PG_FUNCTION_ARGS)
|
||||
result = (CIRCLE *) palloc(sizeof(CIRCLE));
|
||||
|
||||
point_div_point(&result->center, &circle->center, point);
|
||||
result->radius = float8_div(circle->radius, HYPOT(point->x, point->y));
|
||||
result->radius = float8_div(circle->radius, hypot(point->x, point->y));
|
||||
|
||||
PG_RETURN_CIRCLE_P(result);
|
||||
}
|
||||
@@ -5492,71 +5492,3 @@ plist_same(int npts, Point *p1, Point *p2)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Determine the hypotenuse.
|
||||
*
|
||||
* If required, x and y are swapped to make x the larger number. The
|
||||
* traditional formula of x^2+y^2 is rearranged to factor x outside the
|
||||
* sqrt. This allows computation of the hypotenuse for significantly
|
||||
* larger values, and with a higher precision than when using the naive
|
||||
* formula. In particular, this cannot overflow unless the final result
|
||||
* would be out-of-range.
|
||||
*
|
||||
* sqrt( x^2 + y^2 ) = sqrt( x^2( 1 + y^2/x^2) )
|
||||
* = x * sqrt( 1 + y^2/x^2 )
|
||||
* = x * sqrt( 1 + y/x * y/x )
|
||||
*
|
||||
* It is expected that this routine will eventually be replaced with the
|
||||
* C99 hypot() function.
|
||||
*
|
||||
* This implementation conforms to IEEE Std 1003.1 and GLIBC, in that the
|
||||
* case of hypot(inf,nan) results in INF, and not NAN.
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
float8
|
||||
pg_hypot(float8 x, float8 y)
|
||||
{
|
||||
float8 yx,
|
||||
result;
|
||||
|
||||
/* Handle INF and NaN properly */
|
||||
if (isinf(x) || isinf(y))
|
||||
return get_float8_infinity();
|
||||
|
||||
if (isnan(x) || isnan(y))
|
||||
return get_float8_nan();
|
||||
|
||||
/* Else, drop any minus signs */
|
||||
x = fabs(x);
|
||||
y = fabs(y);
|
||||
|
||||
/* Swap x and y if needed to make x the larger one */
|
||||
if (x < y)
|
||||
{
|
||||
float8 temp = x;
|
||||
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* If y is zero, the hypotenuse is x. This test saves a few cycles in
|
||||
* such cases, but more importantly it also protects against
|
||||
* divide-by-zero errors, since now x >= y.
|
||||
*/
|
||||
if (y == 0.0)
|
||||
return x;
|
||||
|
||||
/* Determine the hypotenuse */
|
||||
yx = y / x;
|
||||
result = x * sqrt(1.0 + (yx * yx));
|
||||
|
||||
if (unlikely(isinf(result)))
|
||||
float_overflow_error();
|
||||
if (unlikely(result == 0.0))
|
||||
float_underflow_error();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ pointToRectBoxDistance(Point *point, RectBox *rect_box)
|
||||
else
|
||||
dy = 0;
|
||||
|
||||
return HYPOT(dx, dy);
|
||||
return hypot(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,6 @@ FPge(double A, double B)
|
||||
#define FPge(A,B) ((A) >= (B))
|
||||
#endif
|
||||
|
||||
#define HYPOT(A, B) pg_hypot(A, B)
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* Point - (x,y)
|
||||
@@ -275,11 +274,4 @@ CirclePGetDatum(const CIRCLE *X)
|
||||
#define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
|
||||
#define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
|
||||
|
||||
|
||||
/*
|
||||
* in geo_ops.c
|
||||
*/
|
||||
|
||||
extern float8 pg_hypot(float8 x, float8 y);
|
||||
|
||||
#endif /* GEO_DECLS_H */
|
||||
|
||||
Reference in New Issue
Block a user