-C Change\sthe\srounding\sbehavior\sof\sfloat\spoint\sto\sdecimal\sconversions\ssuch\sthat\nif\sthe\snext\sdigit\sis\s4\sbut\sthe\svalue\sis\swithin\sone\sepsilon\sof\sthe\snext\sdigit\nbeing\s5\sand\sif\sthe\sepsilon\sis\ssmall\scompared\sthe\snumber\sof\sdigits\sto\sbe\nrendered,\sthen\sgo\sahead\sand\sround\sup\sanyhow,\neven\sthough\sthe\scorrect\sbehavior\swould\sbe\sto\sround\sdown.
-D 2024-06-10T14:31:07.017
+C More\saggressive\srounding\sbehavior\sfor\sthe\sround()\sfunction\sonly.\nFormat()\sstill\suses\sthe\sclassic\sbehavior,\sand\sthe\ssame\sbehavior\sexhibited\nby\sprintf()\sin\sglibc.
+D 2024-06-10T18:10:35.427
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/expr.c af9c9242be0df17280faf36c9810339de9df3d7a64ac8d33a5190a1400086ee5
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a
-F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
+F src/func.c 42053720bb3bf4e4e06072f22c2cde4a0477961990a31c4887f3668f8cf4543b
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
-F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9
+F src/printf.c bdb1b615431486709f4a52149468b509a6f04ef5535716e3d05a12c7ddac6de0
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 7e8d23ce7cdbfedf351a47e759f2722e8182ca10fd7580be43f4ce1f1a228145
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7
F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
-F src/util.c cedda44359c51d971557614216085c31d78ee7d23cc89400061c5433855aff64
+F src/util.c 6bd44646223215079588dcac46206c3200d5ba29b9866fabb94dc5a98973f971
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
F src/vdbe.c b05777c3ff2ed7b9dfc347e7cdee18e371aa6811cef1fe83454691b0dbe2cc9f
F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 56af06fa12104a1fe119d7087746011183af053834eac72d0fb69f60d98054c6
-R d2547c87a8223548d3daae3e983f63e3
-T *branch * round-up
-T *sym-round-up *
-T -sym-trunk *
+P 4a790d3b28685f08bbb722057cd6a97aea08a2b2a6098562c6373fd3b5b7206c
+R 73295dcd1493f41c7a4fa684616e652f
U drh
-Z fe023add6bc94c6c74f3cca88a0e7276
+Z 16d69236535ed95782490792d241c4e4
# Remove this line to create a well-formed Fossil manifest.
-4a790d3b28685f08bbb722057cd6a97aea08a2b2a6098562c6373fd3b5b7206c
\ No newline at end of file
+a1b57288d7076cb9e26ac429f01e9264240d6af26243a195b2065cf667bb8bb6
\ No newline at end of file
}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;
}else{
iRound = precision+1;
}
- sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16);
+ sqlite3FpDecode(&s, realvalue, iRound,
+ flag_altform2 ? 26+flag_alternateform : 16);
+ /* ^^^^^^^^^^^^^^^^^^^--- Undocumented behavior:
+ ** When both '#' and '!' flags are present, the rounding behavior
+ ** is changed. See "rule 3" in the sqlite3FpDecode docs. */
if( s.isSpecial ){
if( s.isSpecial==2 ){
bufpt = flag_zeropad ? "null" : "NaN";
}
/*
-** Return true if the first N characters of string z[] are '9'
+** z[] is the complete list of digits for a floating point conversion.
+** The z[iRound] character is a 4. This routine checks to see if the
+** iRound-1 character should be rounded up even though z[iRound] is not
+** a 5.
+**
+** Return true if the 4 is followed by at least three 9s and all digits
+** past the 4 are 9s out to the limit of precision.
*/
-static SQLITE_NOINLINE int allNines(const char *z, int N){
+static SQLITE_NOINLINE int shouldRoundUp(const char *z, int n, int iRound){
int i;
- assert( N>0 );
- for(i=0; i<N; i++){
- if( z[i]!='9' ) return 0;
- }
- return 1;
+ assert( z[iRound]=='4' );
+ for(i=iRound+1; i<n && z[i]=='9'; i++){}
+ if( i<iRound+3 ) return 0;
+ return i>15;
}
/*
** Rule (3) is so that things like round(0.15,1) will come out as 0.2
** even though the stored value for 0.15 is really
** 0.1499999999999999944488848768742172978818416595458984375 and ought
-** to round down to 0.1.
+** to round down to 0.1. Rule (3) is only applied if mxRound==27.
+**
+** This routine is normally only called from printf()/format(). In that
+** case, mxRound is usually 16 but is increased to 26 with the "!" flag.
+** Undocumented behavior: mxRound is 27 with the "#" and "!" flags. The
+** round() function uses this undocumented flag combination to activate
+** rounding rule (3).
*/
void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
int i;
char *z = &p->zBuf[i+1];
if( iRound>mxRound ) iRound = mxRound;
if( z[iRound]>='5'
- || (z[iRound]=='4' && p->n>iRound+5
- && allNines(&z[iRound+1],p->n-iRound-3))
+ || (z[iRound]=='4' && mxRound>=27 && shouldRoundUp(z, p->n, iRound))
){
int j = iRound-1;
while( 1 /*exit-by-break*/ ){