]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the decimal extension, an optional second argument to the
authordrh <>
Fri, 20 Feb 2026 16:21:58 +0000 (16:21 +0000)
committerdrh <>
Fri, 20 Feb 2026 16:21:58 +0000 (16:21 +0000)
decimal() and decimal_exp() functions rounds the value to the
number of significant digits specified by that argument.

FossilOrigin-Name: cb24edf1afc3f9083a4963c5fe232933eccc7c0cb8872aa5fcd336d226b885ef

ext/misc/decimal.c
manifest
manifest.uuid

index f87699f96b157edc8662001dc97dae9eee0377a2..ac9c7c7e5ea313835c59da21edb741b9857858bd 100644 (file)
@@ -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; nZero<p->nDigit && 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; nZero<nDigit && p->a[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     },
index d1d740ff1c3122a50e728fdd78a14840243e56a7..257c23a120f5c44274d24cedff0f5b016e7969f6 100644 (file)
--- 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.
index b83452454a46ef751d97da83d9f907a849a7b5ed..02ddfbd494105a6588022b69b93d5b59a574831c 100644 (file)
@@ -1 +1 @@
-7adb2c0f438a97d377760436b1ac81fffab36e541a2b5ee733bfc7108e0180e5
+cb24edf1afc3f9083a4963c5fe232933eccc7c0cb8872aa5fcd336d226b885ef