From efe86a74b61b4a83c4d60528840dd43f21342554 Mon Sep 17 00:00:00 2001 From: Paul Ramsey Date: Thu, 5 Oct 2017 13:21:52 +0000 Subject: [PATCH] Combine multiple signum definitions (2.4) (References #3878) git-svn-id: http://svn.osgeo.org/postgis/branches/2.4@15902 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/cunit/cu_geodetic.c | 8 -------- liblwgeom/cunit/cu_libgeom.c | 11 +++++++++++ liblwgeom/liblwgeom_internal.h | 13 ++++++++----- liblwgeom/lwalgorithm.c | 16 +--------------- liblwgeom/lwgeodetic.c | 12 ++++++------ liblwgeom/lwgeodetic.h | 5 ----- liblwgeom/lwspheroid.c | 4 ++-- 8 files changed, 29 insertions(+), 41 deletions(-) diff --git a/NEWS b/NEWS index 98b5fcfaa..0f83e434d 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ YYYY/MM/DD - #3845, Gracefully handle short-measure issue - #3871, Performance tweak for geometry cmp function - #3879, Division by zero in some arc cases + - #3878, Single defn of signum in header PostGIS 2.4.0 2017/09/30 diff --git a/liblwgeom/cunit/cu_geodetic.c b/liblwgeom/cunit/cu_geodetic.c index 43994f302..deaacb44f 100644 --- a/liblwgeom/cunit/cu_geodetic.c +++ b/liblwgeom/cunit/cu_geodetic.c @@ -66,13 +66,6 @@ static void point_rad2deg(GEOGRAPHIC_POINT *p) p->lon = rad2deg(p->lon); } -static void test_signum(void) -{ - CU_ASSERT_EQUAL(signum(-5.0),-1); - CU_ASSERT_EQUAL(signum(5.0),1); -} - - static void test_sphere_direction(void) { GEOGRAPHIC_POINT s, e; @@ -1586,7 +1579,6 @@ void geodetic_suite_setup(void) PG_ADD_TEST(suite, test_sphere_direction); PG_ADD_TEST(suite, test_sphere_project); PG_ADD_TEST(suite, test_lwgeom_area_sphere); - PG_ADD_TEST(suite, test_signum); PG_ADD_TEST(suite, test_gbox_from_spherical_coordinates); PG_ADD_TEST(suite, test_gserialized_get_gbox_geocentric); PG_ADD_TEST(suite, test_clairaut); diff --git a/liblwgeom/cunit/cu_libgeom.c b/liblwgeom/cunit/cu_libgeom.c index 9ee4d98a8..c91c17ac0 100644 --- a/liblwgeom/cunit/cu_libgeom.c +++ b/liblwgeom/cunit/cu_libgeom.c @@ -1192,6 +1192,16 @@ void test_gserialized_peek_gbox_p_fails_for_unsupported_cases(void) } } +void test_signum_macro(void); +void test_signum_macro(void) +{ + CU_ASSERT_EQUAL(SIGNUM(-5.0),-1); + CU_ASSERT_EQUAL(SIGNUM( 5.0), 1); + CU_ASSERT_EQUAL(SIGNUM( 0.0), 0); + CU_ASSERT_EQUAL(SIGNUM(10) * 5, 5); + CU_ASSERT_EQUAL(SIGNUM(-10) * 5, -5); +} + /* ** Used by test harness to register the tests in this file. */ @@ -1225,4 +1235,5 @@ void libgeom_suite_setup(void) PG_ADD_TEST(suite, test_gserialized_peek_gbox_p_gets_correct_box); PG_ADD_TEST(suite, test_gserialized_peek_gbox_p_fails_for_unsupported_cases); PG_ADD_TEST(suite, test_gbox_same_2d); + PG_ADD_TEST(suite, test_signum_macro); } diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index a04c355d4..ce3c668a8 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -121,6 +121,14 @@ #define SIZE_GET(varsize) (((varsize) >> 2) & 0x3FFFFFFF) #define SIZE_SET(varsize, size) (((varsize) & 0x00000003)|(((size) & 0x3FFFFFFF) << 2 )) +/** +* Macro that returns: +* -1 if n < 0, +* 1 if n > 0, +* 0 if n == 0 +*/ +#define SIGNUM(n) (((n) > 0) - ((n) < 0)) + /** * Tolerance used to determine equality. */ @@ -198,11 +206,6 @@ LWLINE* lwline_simplify(const LWLINE *iline, double dist, int preserve_collapsed LWPOLY* lwpoly_simplify(const LWPOLY *ipoly, double dist, int preserve_collapsed); LWCOLLECTION* lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed); -/* -* Computational geometry -*/ -int signum(double n); - /* * The possible ways a pair of segments can interact. Returned by lw_segment_intersects */ diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index 787acddf5..69b818a78 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -27,17 +27,6 @@ #include "lwgeom_log.h" #include /* for tolower */ - -/** -* Returns -1 if n < 0.0 and 1 if n > 0.0 -*/ -int signum(double n) -{ - if( n < 0 ) return -1; - if( n > 0 ) return 1; - return 0; -} - int p4d_same(const POINT4D *p1, const POINT4D *p2) { @@ -75,10 +64,7 @@ p2d_same(const POINT2D *p1, const POINT2D *p2) int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q) { double side = ( (q->x - p1->x) * (p2->y - p1->y) - (p2->x - p1->x) * (q->y - p1->y) ); - if ( side == 0.0 ) - return 0; - else - return signum(side); + return SIGNUM(side); } /** diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c index 8d2391a0f..b86c68e58 100644 --- a/liblwgeom/lwgeodetic.c +++ b/liblwgeom/lwgeodetic.c @@ -630,8 +630,8 @@ void y_to_z(POINT3D *p) int crosses_dateline(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e) { - double sign_s = signum(s->lon); - double sign_e = signum(e->lon); + double sign_s = SIGNUM(s->lon); + double sign_e = SIGNUM(e->lon); double ss = fabs(s->lon); double ee = fabs(e->lon); if ( sign_s == sign_e ) @@ -833,7 +833,7 @@ int edge_contains_coplanar_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POIN } /* Over the pole, we need normalize latitude and do this calculation in latitude */ - if ( FP_EQUALS( slon, M_PI ) && ( signum(g.start.lon) != signum(g.end.lon) || FP_EQUALS(dlon, M_PI) ) ) + if ( FP_EQUALS( slon, M_PI ) && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) || FP_EQUALS(dlon, M_PI) ) ) { LWDEBUG(4, "over the pole..."); /* Antipodal, everything (or nothing?) is inside */ @@ -877,7 +877,7 @@ int edge_contains_coplanar_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POIN } /* Dateline crossing, flip everything to the opposite hemisphere */ - else if ( slon > M_PI && ( signum(g.start.lon) != signum(g.end.lon) ) ) + else if ( slon > M_PI && ( SIGNUM(g.start.lon) != SIGNUM(g.end.lon) ) ) { LWDEBUG(4, "crosses dateline, flip longitudes..."); if ( g.start.lon > 0.0 ) @@ -984,7 +984,7 @@ static double sphere_excess(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b double c_dist = sphere_distance(a, b); double hca = sphere_direction(c, a, b_dist); double hcb = sphere_direction(c, b, a_dist); - double sign = signum(hcb-hca); + double sign = SIGNUM(hcb-hca); double ss = (a_dist + b_dist + c_dist) / 2.0; double E = tan(ss/2.0)*tan((ss-a_dist)/2.0)*tan((ss-b_dist)/2.0)*tan((ss-c_dist)/2.0); return 4.0 * atan(sqrt(fabs(E))) * sign; @@ -1013,7 +1013,7 @@ int edge_contains_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *p) */ double z_to_latitude(double z, int top) { - double sign = signum(z); + double sign = SIGNUM(z); double tlat = acos(z); LWDEBUGF(4, "inputs: z(%.8g) sign(%.8g) tlat(%.8g)", z, sign, tlat); if (FP_IS_ZERO(z)) diff --git a/liblwgeom/lwgeodetic.h b/liblwgeom/lwgeodetic.h index a43b3f1b7..b186259ca 100644 --- a/liblwgeom/lwgeodetic.h +++ b/liblwgeom/lwgeodetic.h @@ -74,11 +74,6 @@ typedef struct #define deg2rad(d) (M_PI * (d) / 180.0) #define rad2deg(r) (180.0 * (r) / M_PI) -/** -* Ape a java function -*/ -#define signum(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : (a))) - /** * Bitmask elements for edge_intersects() return value. diff --git a/liblwgeom/lwspheroid.c b/liblwgeom/lwspheroid.c index c78c36e38..2d24f250f 100644 --- a/liblwgeom/lwspheroid.c +++ b/liblwgeom/lwspheroid.c @@ -487,7 +487,7 @@ static double spheroid_striparea(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POI LWDEBUGF(4, "tE %.12g", tE); ratio = (bE + tE)/tE; - sign = signum(B.lon - A.lon); + sign = SIGNUM(B.lon - A.lon); return (baseArea + topArea / ratio) * sign; } @@ -511,7 +511,7 @@ static double ptarray_area_spheroid(const POINTARRAY *pa, const SPHEROID *sphero /* Get the raw min/max values for the latitudes */ ptarray_calculate_gbox_cartesian(pa, &gbox2d); - if ( signum(gbox2d.ymin) != signum(gbox2d.ymax) ) + if ( SIGNUM(gbox2d.ymin) != SIGNUM(gbox2d.ymax) ) lwerror("ptarray_area_spheroid: cannot handle ptarray that crosses equator"); /* Geodetic bbox < 0.0 implies geometry is entirely in southern hemisphere */ -- 2.50.1