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