[postgis-tickets] r15772 - Remove the local hacks for float rounding and go

Paul Ramsey pramsey at cleverelephant.ca
Tue Sep 19 14:02:06 PDT 2017


Author: pramsey
Date: 2017-09-19 14:02:06 -0700 (Tue, 19 Sep 2017)
New Revision: 15772

Modified:
   trunk/liblwgeom/liblwgeom.h.in
   trunk/liblwgeom/lwgeom_api.c
   trunk/regress/lwgeom_regress_expected
Log:
Remove the local hacks for float rounding and go
with system level functions, that are hopefully 
more optimized. Also, this seems to provide more
correct results than the old code!
(Closes #3852)


Modified: trunk/liblwgeom/liblwgeom.h.in
===================================================================
--- trunk/liblwgeom/liblwgeom.h.in	2017-09-19 18:08:45 UTC (rev 15771)
+++ trunk/liblwgeom/liblwgeom.h.in	2017-09-19 21:02:06 UTC (rev 15772)
@@ -651,7 +651,7 @@
 extern uint32_t gserialized_max_header_size(void);
 
 /**
-* Returns the size in bytes of the header, from the start of the 
+* Returns the size in bytes of the header, from the start of the
 * object up to the type number.
 */
 extern uint32_t gserialized_header_size(const GSERIALIZED *gser);
@@ -710,10 +710,10 @@
 /**
 * Return -1 if g1 is "less than" g2, 1 if g1 is "greater than"
 * g2 and 0 if g1 and g2 are the "same". Equality is evaluated
-* with a memcmp and size check. So it is possible that two 
-* identical objects where one lacks a bounding box could be 
+* with a memcmp and size check. So it is possible that two
+* identical objects where one lacks a bounding box could be
 * evaluated as non-equal initially. Greater and less than
-* are evaluated by calculating a sortable key from the center 
+* are evaluated by calculating a sortable key from the center
 * point of the object bounds.
 */
 extern int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2);
@@ -1165,8 +1165,6 @@
 
 extern float  next_float_down(double d);
 extern float  next_float_up(double d);
-extern double next_double_down(float d);
-extern double next_double_up(float d);
 
 /* general utilities 2D */
 extern double  distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2);

Modified: trunk/liblwgeom/lwgeom_api.c
===================================================================
--- trunk/liblwgeom/lwgeom_api.c	2017-09-19 18:08:45 UTC (rev 15771)
+++ trunk/liblwgeom/lwgeom_api.c	2017-09-19 21:02:06 UTC (rev 15772)
@@ -47,115 +47,15 @@
 }
 
 
-/**********************************************************************
- * BOX routines
- *
- * returns the float thats very close to the input, but <=
- *  handles the funny differences in float4 and float8 reps.
- **********************************************************************/
-
-typedef union
+inline float
+next_float_down(double d)
 {
-	float value;
-	uint32_t word;
-} ieee_float_shape_type;
-
-#define GET_FLOAT_WORD(i,d)			\
-	do {					\
-		ieee_float_shape_type gf_u;	\
-		gf_u.value = (d);		\
-		(i) = gf_u.word;		\
-	} while (0)
-
-
-#define SET_FLOAT_WORD(d,i)			\
-	do {					\
-		ieee_float_shape_type sf_u;	\
-		sf_u.word = (i);		\
-		(d) = sf_u.value;		\
-	} while (0)
-
-
-/*
- * Returns the next smaller or next larger float
- * from x (in direction of y).
- */
-static float
-nextafterf_custom(float x, float y)
-{
-	int hx,hy,ix,iy;
-
-	GET_FLOAT_WORD(hx,x);
-	GET_FLOAT_WORD(hy,y);
-	ix = hx&0x7fffffff;             /* |x| */
-	iy = hy&0x7fffffff;             /* |y| */
-
-	if ((ix>0x7f800000) ||   /* x is nan */
-	        (iy>0x7f800000))     /* y is nan */
-		return x+y;
-	if (x==y) return y;              /* x=y, return y */
-	if (ix==0)
-	{
-		/* x == 0 */
-		SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
-		y = x*x;
-		if (y==x) return y;
-		else return x;   /* raise underflow flag */
-	}
-	if (hx>=0)
-	{
-		/* x > 0 */
-		if (hx>hy)
-		{
-			/* x > y, x -= ulp */
-			hx -= 1;
-		}
-		else
-		{
-			/* x < y, x += ulp */
-			hx += 1;
-		}
-	}
-	else
-	{
-		/* x < 0 */
-		if (hy>=0||hx>hy)
-		{
-			/* x < y, x -= ulp */
-			hx -= 1;
-		}
-		else
-		{
-			/* x > y, x += ulp */
-			hx += 1;
-		}
-	}
-	hy = hx&0x7f800000;
-	if (hy>=0x7f800000) return x+x;  /* overflow  */
-	if (hy<0x00800000)
-	{
-		/* underflow */
-		y = x*x;
-		if (y!=x)
-		{
-			/* raise underflow flag */
-			SET_FLOAT_WORD(y,hx);
-			return y;
-		}
-	}
-	SET_FLOAT_WORD(x,hx);
-	return x;
-}
-
-
-float next_float_down(double d)
-{
 	float result  = d;
 
-	if ( ((double) result) <=d)
+	if ( ((double)result) <=d )
 		return result;
 
-	return nextafterf_custom(result, result - 1000000);
+	return nextafterf(result, -1*FLT_MAX);
 
 }
 
@@ -163,49 +63,20 @@
  * Returns the float thats very close to the input, but >=.
  * handles the funny differences in float4 and float8 reps.
  */
-float
+inline float
 next_float_up(double d)
 {
 	float result  = d;
 
-	if ( ((double) result) >=d)
+	if ( ((double)result) >=d )
 		return result;
 
-	return nextafterf_custom(result, result + 1000000);
+	return nextafterf(result, FLT_MAX);
 }
 
 
-/*
- * Returns the double thats very close to the input, but <.
- * handles the funny differences in float4 and float8 reps.
- */
-double
-next_double_down(float d)
-{
-	double result  = d;
 
-	if ( result < d)
-		return result;
 
-	return nextafterf_custom(result, result - 1000000);
-}
-
-/*
- * Returns the double thats very close to the input, but >
- * handles the funny differences in float4 and float8 reps.
- */
-double
-next_double_up(float d)
-{
-	double result  = d;
-
-	if ( result > d)
-		return result;
-
-	return nextafterf_custom(result, result + 1000000);
-}
-
-
 /************************************************************************
  * POINTARRAY support functions
  *

Modified: trunk/regress/lwgeom_regress_expected
===================================================================
--- trunk/regress/lwgeom_regress_expected	2017-09-19 18:08:45 UTC (rev 15771)
+++ trunk/regress/lwgeom_regress_expected	2017-09-19 21:02:06 UTC (rev 15772)
@@ -15,9 +15,9 @@
 #3069|BOX(0 0,1 1)
 #3069|BOX(1 1,1 1)
 #3069|BOX(0 0,1 1)
-BoundingDiagonal1|SRID=4326;LINESTRING(999999986991104 999999986991104,999999986991104 999999986991104)
+BoundingDiagonal1|SRID=4326;LINESTRING(999999986991104 999999986991104,1.00000005409997e+15 1.00000005409997e+15)
 BoundingDiagonal2|SRID=4326;LINESTRING(1e+15 1e+15,1e+15 1e+15)
-BoundingDiagonal3|SRID=4326;LINESTRING(999999986991104 999999986991104,999999986991104 999999986991104)
+BoundingDiagonal3|SRID=4326;LINESTRING(999999986991104 999999986991104,1.00000005409997e+15 1.00000005409997e+15)
 BoundingDiagonal4|SRID=3857;LINESTRING(-1 -2 -8 2,1 2 3 9)
 BoundingDiagonal5|SRID=3857;LINESTRINGM(4 4 0,5 4 1)
 BoundingDiagonal6|SRID=3857;LINESTRINGM EMPTY



More information about the postgis-tickets mailing list