phypot-2.patch
text/plain
Filename: phypot-2.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/utils/adt/geo_ops.c | 58 | 0 |
| src/include/utils/geo_decls.h | 2 | 1 |
*** a/src/backend/utils/adt/geo_ops.c
--- b/src/backend/utils/adt/geo_ops.c
***************
*** 5410,5412 **** plist_same(int npts, Point *p1, Point *p2)
--- 5410,5470 ----
return FALSE;
}
+
+
+ /*-------------------------------------------------------------------------
+ * Determine the hypotenuse.
+ *
+ * If required, x and y are swapped to make x the larger number. The
+ * traditional formulae 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 otherwise normally
+ * possible.
+ *
+ * Only arguments of > 1.27e308 are at risk of causing overflow. Whereas
+ * the naive approach limits arguments to < 9.5e153.
+ *
+ * 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.
+ *-----------------------------------------------------------------------*/
+ double
+ phypot(double x, double y)
+ {
+ double yx;
+
+ if (isinf(x) || isinf(y))
+ return get_float8_infinity();
+
+ if (isnan(x) || isnan(y))
+ return get_float8_nan();
+
+ x = fabs(x);
+ y = fabs(y);
+
+ /* If required, swap x and y */
+ if (x < y)
+ {
+ double temp = x;
+
+ x = y;
+ y = temp;
+ }
+
+ /*
+ * If y is zero, the hypotenuse is x, whether or not x is also zero. This
+ * test protects against divide-by-zero errors.
+ */
+ if (y == 0.0)
+ return x;
+
+ /* Determine the hypotenuse */
+ yx = y / x;
+ return x * sqrt(1.0 + (yx * yx));
+ }
*** a/src/include/utils/geo_decls.h
--- b/src/include/utils/geo_decls.h
***************
*** 50,56 ****
#define FPge(A,B) ((A) >= (B))
#endif
! #define HYPOT(A, B) sqrt((A) * (A) + (B) * (B))
/*---------------------------------------------------------------------
* Point - (x,y)
--- 50,56 ----
#define FPge(A,B) ((A) >= (B))
#endif
! #define HYPOT(A, B) phypot((A), (B))
/*---------------------------------------------------------------------
* Point - (x,y)
***************
*** 211,216 **** extern Datum point_div(PG_FUNCTION_ARGS);
--- 211,217 ----
/* private routines */
extern double point_dt(Point *pt1, Point *pt2);
extern double point_sl(Point *pt1, Point *pt2);
+ extern double phypot(double x, double y);
/* public lseg routines */
extern Datum lseg_in(PG_FUNCTION_ARGS);