Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The aggressive rounding behavior is now only accessible using the internal sqlite3MPrintf() function. The round() SQL function uses that internal function so it can access the aggressive rounding. But ordinary extensions and the format() SQL function cannot. Update: Superseded by round-up-2 branch |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | round-up |
Files: | files | file ages | folders |
SHA3-256: |
3dec4b35ecd68a4dace7ea17f046231e |
User & Date: | drh 2024-06-10 18:30:44 |
Original Comment: | The aggressive rounding behavior is now only accessible using the internal sqlite3MPrintf() function. The round() SQL function uses that internal function so it can access the aggressive rounding. But ordinary extensions and the format() SQL function cannot. |
Context
2024-06-10
| ||
18:30 | The aggressive rounding behavior is now only accessible using the internal sqlite3MPrintf() function. The round() SQL function uses that internal function so it can access the aggressive rounding. But ordinary extensions and the format() SQL function cannot. Update: Superseded by round-up-2 branch (Closed-Leaf check-in: 3dec4b35 user: drh tags: round-up) | |
18:10 | More aggressive rounding behavior for the round() function only. Format() still uses the classic behavior, and the same behavior exhibited by printf() in glibc. (check-in: a1b57288 user: drh tags: round-up) | |
Changes
Changes to src/func.c.
︙ | ︙ | |||
457 458 459 460 461 462 463 | ** otherwise use printf. */ if( r<-4503599627370496.0 || r>+4503599627370496.0 ){ /* The value has no fractional part so there is nothing to round */ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ | > | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** otherwise use printf. */ if( r<-4503599627370496.0 || r>+4503599627370496.0 ){ /* The value has no fractional part so there is nothing to round */ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ sqlite3 *db = sqlite3_context_db_handle(context); zBuf = sqlite3MPrintf(db,"%!.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; } sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3DbFreeNN(db, zBuf); } sqlite3_result_double(context, r); } #endif /* ** Allocate nByte bytes of space using sqlite3Malloc(). If the |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | break; case etFLOAT: case etEXP: case etGENERIC: { FpDecode s; int iRound; int j; if( bArgList ){ realvalue = getDoubleArg(pArgList); }else{ realvalue = va_arg(ap,double); } if( precision<0 ) precision = 6; /* Set default precision */ #ifdef SQLITE_FP_PRECISION_LIMIT if( precision>SQLITE_FP_PRECISION_LIMIT ){ precision = SQLITE_FP_PRECISION_LIMIT; } #endif if( xtype==etFLOAT ){ iRound = -precision; }else if( xtype==etGENERIC ){ if( precision==0 ) precision = 1; iRound = precision; }else{ iRound = precision+1; } | > > > > > > | < < < < | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | break; case etFLOAT: case etEXP: case etGENERIC: { FpDecode s; int iRound; int j; int mx; if( bArgList ){ realvalue = getDoubleArg(pArgList); }else{ realvalue = va_arg(ap,double); } if( precision<0 ) precision = 6; /* Set default precision */ #ifdef SQLITE_FP_PRECISION_LIMIT if( precision>SQLITE_FP_PRECISION_LIMIT ){ precision = SQLITE_FP_PRECISION_LIMIT; } #endif if( xtype==etFLOAT ){ iRound = -precision; }else if( xtype==etGENERIC ){ if( precision==0 ) precision = 1; iRound = precision; }else{ iRound = precision+1; } if( flag_altform2 ){ mx = 26 + ((pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)!=0); }else{ mx = 16; } sqlite3FpDecode(&s, realvalue, iRound, mx); if( s.isSpecial ){ if( s.isSpecial==2 ){ bufpt = flag_zeropad ? "null" : "NaN"; length = sqlite3Strlen30(bufpt); break; }else if( flag_zeropad ){ s.z[0] = '9'; |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | ** Rounding Behavior: ** ** (1) If the next digit is 3 or less, then truncate. Do not round. ** ** (2) If the next digit is 5 or more, then round up. ** ** (3) Round up if the next digit is a 4 followed by three or | | | > | < < | | < < | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | ** Rounding Behavior: ** ** (1) If the next digit is 3 or less, then truncate. Do not round. ** ** (2) If the next digit is 5 or more, then round up. ** ** (3) Round up if the next digit is a 4 followed by three or ** more 9 digits and all significant digits after the 4 are ** 9 and mxRound is 27. Otherwise truncate. ** ** Rule (3) is used by the built-in round() function to do more aggressive ** rounding 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. Rule (3) is only applied if mxRound==27. ** And mxRound is only 27 if the internal sqlite3MPrintf() formatter is ** used and the "!" flag is included. */ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ int i; u64 v; int e, exp = 0; p->isSpecial = 0; p->z = p->zBuf; |
︙ | ︙ |