From: drh <> Date: Fri, 20 Feb 2026 16:21:58 +0000 (+0000) Subject: In the decimal extension, an optional second argument to the X-Git-Tag: version-3.52.0~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62546d4b1ff9211ccff922f622ee73871b1ed2b0;p=thirdparty%2Fsqlite.git In the decimal extension, an optional second argument to the decimal() and decimal_exp() functions rounds the value to the number of significant digits specified by that argument. FossilOrigin-Name: cb24edf1afc3f9083a4963c5fe232933eccc7c0cb8872aa5fcd336d226b885ef --- diff --git a/ext/misc/decimal.c b/ext/misc/decimal.c index f87699f96b..ac9c7c7e5e 100644 --- a/ext/misc/decimal.c +++ b/ext/misc/decimal.c @@ -291,12 +291,36 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){ sqlite3_result_text(pCtx, z, i, sqlite3_free); } +/* +** Round a decimal value to N significant digits. N must be positive. +*/ +static void decimal_round(Decimal *p, int N){ + int i; + int nZero; + if( N<1 ) return; + for(nZero=0; nZeronDigit && p->a[nZero]==0; nZero++){} + N += nZero; + if( p->nDigit<=N ) return; + if( p->a[N]>4 ){ + p->a[N-1]++; + for(i=N-1; i>0 && p->a[i]>9; i--){ + p->a[i] = 0; + p->a[i-1]++; + } + if( p->a[0]>9 ){ + p->a[0] = 1; + p->nFrac--; + } + } + memset(&p->a[N], 0, p->nDigit - N); +} + /* ** Make the given Decimal the result in an format similar to '%+#e'. ** In other words, show exponential notation with leading and trailing ** zeros omitted. */ -static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){ +static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p, int N){ char *z; /* The output buffer */ int i; /* Loop counter */ int nZero; /* Number of leading zeros */ @@ -314,8 +338,10 @@ static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){ sqlite3_result_null(pCtx); return; } - for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} + if( N<1 ) N = 0; + for(nDigit=p->nDigit; nDigit>N && p->a[nDigit-1]==0; nDigit--){} for(nZero=0; nZeroa[nZero]==0; nZero++){} + N += nZero; nFrac = p->nFrac + (nDigit - p->nDigit); nDigit -= nZero; z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 ); @@ -677,10 +703,16 @@ static void decimalFunc( sqlite3_value **argv ){ Decimal *p = decimal_new(context, argv[0], 0); - UNUSED_PARAMETER(argc); + int N; + if( argc==2 ){ + N = sqlite3_value_int(argv[1]); + if( N>0 ) decimal_round(p, N); + }else{ + N = 0; + } if( p ){ if( sqlite3_user_data(context)!=0 ){ - decimal_result_sci(context, p); + decimal_result_sci(context, p, N); }else{ decimal_result(context, p); } @@ -850,7 +882,7 @@ static void decimalPow2Func( UNUSED_PARAMETER(argc); if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ Decimal *pA = decimalPow2(sqlite3_value_int(argv[0])); - decimal_result_sci(context, pA); + decimal_result_sci(context, pA, 0); decimal_free(pA); } } @@ -871,7 +903,9 @@ int sqlite3_decimal_init( void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { { "decimal", 1, 0, decimalFunc }, + { "decimal", 2, 0, decimalFunc }, { "decimal_exp", 1, 1, decimalFunc }, + { "decimal_exp", 2, 1, decimalFunc }, { "decimal_cmp", 2, 0, decimalCmpFunc }, { "decimal_add", 2, 0, decimalAddFunc }, { "decimal_sub", 2, 0, decimalSubFunc }, diff --git a/manifest b/manifest index d1d740ff1c..257c23a120 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scse\sin\sthe\sfiddle.debug\sbuild\swhere\sit\scould\snot\soverwrite\sits\sread-only/generated\sindex.html. -D 2026-02-20T14:22:09.912 +C In\sthe\sdecimal\sextension,\san\soptional\ssecond\sargument\sto\sthe\ndecimal()\sand\sdecimal_exp()\sfunctions\srounds\sthe\svalue\sto\sthe\nnumber\sof\ssignificant\sdigits\sspecified\sby\sthat\sargument. +D 2026-02-20T16:21:58.730 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -370,7 +370,7 @@ F ext/misc/completion.c c27b64fdd0943c1b7f152376599814cee2641f7d67a7bb9bd2b957c2 F ext/misc/compress.c 8191118b9b73e7796c961790db62d35d9b0fb724b045e005a5713dc9e0795565 F ext/misc/csv.c e82124eabee0e692d7b90ab8b2c34fadbf7b375279f102567fa06e4da4b771bf F ext/misc/dbdump.c 678f1b9ae2317b4473f65d03132a2482c3f4b08920799ed80feedd2941a06680 -F ext/misc/decimal.c d4883de142f6dcd36eda23da40b55e2b51374e7b01eb54a7173940191389fc5e +F ext/misc/decimal.c 38aa18b29e96c745c78725ef3740a53f4b2b8cdfa226dfab13aaf2168a071db7 F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b F ext/misc/fileio.c 452300ca34fadafd2bb9eb09557de5a518da1fd2349f9f9cedd22b1566a7164f @@ -2195,8 +2195,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 8660d3e94cbe892693554df282bce0fa8c7aedbc5e020cab647cbbff3d7e55b7 -R 389af95283f5ab275172b5b1245f2df2 -U stephan -Z 85bcd6f2a42107fa459e33d70b89b165 +P 7adb2c0f438a97d377760436b1ac81fffab36e541a2b5ee733bfc7108e0180e5 +R d3925fd721dfabc8744fb8ec5748bbad +U drh +Z a53353c83d76fce8dcafd070d72a5289 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b83452454a..02ddfbd494 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7adb2c0f438a97d377760436b1ac81fffab36e541a2b5ee733bfc7108e0180e5 +cb24edf1afc3f9083a4963c5fe232933eccc7c0cb8872aa5fcd336d226b885ef