That last patch was a bad workaround -- please ignore it.  

The et_getdigit function does count the number of significant digits returned.  
However, it has a wrong boundary.  Limiting the number of significant digits is 
more correct than changing the output precision.  So, the following changes 
(against the amalgamation) will always use and round to the same number of 
significant digits specified by a preprocessor macro SQLITE_SIGNIFICANT_DIGITS, 
which defaults to 14.  The rounding function now works correctly again (I broke 
it under certain circumstances in the other patch).  Also, all output format 
functions use the default specified significant digits and round equally.  If 
you use a specific format in SQL printf function, it will behave properly, and 
if you do not specify a precision or exceed the number of significant digits, 
the results will be correct.  Output in the vdbe code is unchanged (only user 
value I/O is affected by removing the precision specifier from the printf's in 
vdbemem.c).

--- sqlite3.c
+++ sqlite3.c
@@ -19594,17 +19594,20 @@
 ** Example:
 **     input:     *val = 3.14159
 **     output:    *val = 1.4159    function return = '3'
 **
 ** The counter *cnt is incremented each time.  After counter exceeds
-** 16 (the number of significant digits in a 64-bit float) '0' is
-** always returned.
+** SQLITE_SIGNIFICANT_DIGITS '0' is always returned.  Default to 14
+** digits for IEEE 754 Floating Point
 */
+#ifndef SQLITE_SIGNIFICANT_DIGITS
+#define SQLITE_SIGNIFICANT_DIGITS 14
+#endif
 static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
   int digit;
   LONGDOUBLE_TYPE d;
-  if( (*cnt)++ >= 16 ) return '0';
+  if( (*cnt)++ >= SQLITE_SIGNIFICANT_DIGITS ) return '0';
   digit = (int)*val;
   d = digit;
   digit += '0';
   *val = (*val - d)*10.0;
   return (char)digit;
@@ -59458,11 +59461,11 @@
   */
   if( fg & MEM_Int ){
     sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
   }else{
     assert( fg & MEM_Real );
-    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
+    sqlite3_snprintf(nByte, pMem->z, "%!g", pMem->r);
   }
   pMem->n = sqlite3Strlen30(pMem->z);
   pMem->enc = SQLITE_UTF8;
   pMem->flags |= MEM_Str|MEM_Term;
   sqlite3VdbeChangeEncoding(pMem, enc);
@@ -65065,11 +65068,11 @@
       if( pVar->flags & MEM_Null ){
         sqlite3StrAccumAppend(&out, "NULL", 4);
       }else if( pVar->flags & MEM_Int ){
         sqlite3XPrintf(&out, "%lld", pVar->u.i);
       }else if( pVar->flags & MEM_Real ){
-        sqlite3XPrintf(&out, "%!.15g", pVar->r);
+        sqlite3XPrintf(&out, "%!g", pVar->r);
       }else if( pVar->flags & MEM_Str ){
 #ifndef SQLITE_OMIT_UTF16
         u8 enc = ENC(db);
         if( enc!=SQLITE_UTF8 ){
           Mem utf8;

I'll send the canonical source patches shortly.



---
()  ascii ribbon campaign against html e-mail
/\  www.asciiribbon.org




_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to