summaryrefslogtreecommitdiff
path: root/ext/rtree/rtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/rtree/rtree.c')
-rw-r--r--ext/rtree/rtree.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c
index d6cdde9..66da481 100644
--- a/ext/rtree/rtree.c
+++ b/ext/rtree/rtree.c
@@ -2740,6 +2740,36 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
}
/*
+** Rounding constants for float->double conversion.
+*/
+#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
+#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
+
+#if !defined(SQLITE_RTREE_INT_ONLY)
+/*
+** Convert an sqlite3_value into an RtreeValue (presumably a float)
+** while taking care to round toward negative or positive, respectively.
+*/
+static RtreeValue rtreeValueDown(sqlite3_value *v){
+ double d = sqlite3_value_double(v);
+ float f = (float)d;
+ if( f>d ){
+ f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
+ }
+ return f;
+}
+static RtreeValue rtreeValueUp(sqlite3_value *v){
+ double d = sqlite3_value_double(v);
+ float f = (float)d;
+ if( f<d ){
+ f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
+ }
+ return f;
+}
+#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
+
+
+/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
@@ -2775,8 +2805,8 @@ static int rtreeUpdate(
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]);
- cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]);
+ cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
+ cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT;
goto constraint;