diff options
author | drh <drh@noemail.net> | 2019-05-24 22:58:16 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-05-24 22:58:16 +0000 |
commit | a0ed86bc372b5a14ab81027644c2bc37e62556da (patch) | |
tree | 583984f46ba5ba474683c2bd16381e3eaaa7ed5c /src | |
parent | 98d63579be4de635e5f687929ba2553f5b725661 (diff) | |
download | sqlite-a0ed86bc372b5a14ab81027644c2bc37e62556da.tar.gz sqlite-a0ed86bc372b5a14ab81027644c2bc37e62556da.zip |
Improvements to rounding behavior in the round() and printf() functions.
FossilOrigin-Name: 641b2d210541b4d5a1a9e57d7dcf5ce5dfd7ff4d2dc6277ba0582869f48fc946
Diffstat (limited to 'src')
-rw-r--r-- | src/printf.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/printf.c b/src/printf.c index 0f66bc29f..f1634799b 100644 --- a/src/printf.c +++ b/src/printf.c @@ -99,6 +99,12 @@ static const et_info fmtinfo[] = { { 'r', 10, 1, etORDINAL, 0, 0 }, }; +/* Floating point constants used for rounding */ +static const double arRound[] = { + 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05, + 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10, +}; + /* ** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point ** conversions will work. @@ -517,8 +523,13 @@ void sqlite3_str_vappendf( } if( xtype==etGENERIC && precision>0 ) precision--; testcase( precision>0xfff ); - for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} - if( xtype==etFLOAT ) realvalue += rounder; + idx = precision & 0xfff; + rounder = arRound[idx%10]; + while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } + if( xtype==etFLOAT ){ + if( precision<17) rounder += realvalue*2.0e-16; + realvalue += rounder; + } /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; if( sqlite3IsNaN((double)realvalue) ){ |