41 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			41 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
Index: src/vdbemem.c
 | 
						|
==================================================================
 | 
						|
--- src/vdbemem.c
 | 
						|
+++ src/vdbemem.c
 | 
						|
@@ -579,10 +579,22 @@
 | 
						|
 
 | 
						|
   pMem->u.r = sqlite3VdbeRealValue(pMem);
 | 
						|
   MemSetTypeFlag(pMem, MEM_Real);
 | 
						|
   return SQLITE_OK;
 | 
						|
 }
 | 
						|
+
 | 
						|
+/* Compare a floating point value to an integer.  Return true if the two
 | 
						|
+** values are the same within the precision of the floating point value.
 | 
						|
+**
 | 
						|
+** For some versions of GCC on 32-bit machines, if you do the more obvious
 | 
						|
+** comparison of "r1==(double)i" you sometimes get an answer of false even
 | 
						|
+** though the r1 and (double)i values are bit-for-bit the same.
 | 
						|
+*/
 | 
						|
+static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
 | 
						|
+  double r2 = (double)i;
 | 
						|
+  return memcmp(&r1, &r2, sizeof(r1))==0;
 | 
						|
+}
 | 
						|
 
 | 
						|
 /*
 | 
						|
 ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
 | 
						|
 ** Invalidate any prior representations.
 | 
						|
 **
 | 
						|
@@ -599,11 +611,11 @@
 | 
						|
     if( rc==0 ){
 | 
						|
       MemSetTypeFlag(pMem, MEM_Int);
 | 
						|
     }else{
 | 
						|
       i64 i = pMem->u.i;
 | 
						|
       sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
 | 
						|
-      if( rc==1 && pMem->u.r==(double)i ){
 | 
						|
+      if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
 | 
						|
         pMem->u.i = i;
 | 
						|
         MemSetTypeFlag(pMem, MEM_Int);
 | 
						|
       }else{
 | 
						|
         MemSetTypeFlag(pMem, MEM_Real);
 | 
						|
       }
 |