1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Improved rounding policy.

FossilOrigin-Name: 6f1122e942b8269552daaf13d647d200d8546ec25f36310d67037c6b58d09976
This commit is contained in:
drh
2023-07-01 17:56:00 +00:00
parent 9ee9444a0a
commit 17c20bb15e
7 changed files with 20 additions and 19 deletions

View File

@@ -461,7 +461,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}else if( n==0 ){
r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
zBuf = sqlite3_mprintf("%!.*f",n,r);
if( zBuf==0 ){
sqlite3_result_error_nomem(context);
return;

View File

@@ -502,7 +502,7 @@ void sqlite3_str_vappendf(
}else{
iRound = precision+1;
}
sqlite3FpDecode(&s, realvalue, iRound);
sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16);
if( s.isSpecial ){
if( s.isSpecial==2 ){
bufpt = flag_zeropad ? "null" : "NaN";

View File

@@ -4610,7 +4610,7 @@ struct FpDecode {
char z[24]; /* Significiant digits */
};
void sqlite3FpDecode(FpDecode*,double,int);
void sqlite3FpDecode(FpDecode*,double,int,int);
char *sqlite3MPrintf(sqlite3*,const char*, ...);
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)

View File

@@ -937,7 +937,7 @@ int sqlite3Atoi(const char *z){
** decimal point if n is negative. No rounding is performed if
** n is zero.
*/
void sqlite3FpDecode(FpDecode *p, double r, int iRound){
void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
int i;
u64 v;
int e, exp = 0;
@@ -972,7 +972,7 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound){
while( r>=1.0e+119 ){ exp+=100; r /= 1.0e+100; }
while( r>=1.0e+29 ){ exp+=10; r /= 1.0e+10; }
while( r>=1.0e+19 ){ exp++; r /= 10.0; }
}else if( r<1.0e+17 ){
}else{
while( r<1.0e-97 ){ exp-=100; r *= 1.0e+100; }
while( r<1.0e+07 ){ exp-=10; r *= 1.0e+10; }
while( r<1.0e+17 ){ exp--; r *= 10.0; }
@@ -991,8 +991,9 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound){
p->iDP++;
}
}
if( iRound>0 && iRound<p->n ){
if( iRound>0 && (iRound<p->n || p->n>mxRound) ){
char *z = &p->z[i+1];
if( iRound>mxRound ) iRound = mxRound;
p->n = iRound;
if( z[iRound]>='5' ){
int j = iRound-1;