]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Increase the precision of double → text conversions that happen in
authordrh <>
Sat, 21 Feb 2026 10:57:02 +0000 (10:57 +0000)
committerdrh <>
Sat, 21 Feb 2026 10:57:02 +0000 (10:57 +0000)
sqlite3_column_text(), or sqlite3_value_text(), or in the CAST() operator,
or similar, so that round-tripping the value back to double results in
exactly the same value.

FossilOrigin-Name: ef0049e3ade304f64e1ab97e52e1e21379e4db461f3fa80dac8e544fb90d622f

manifest
manifest.uuid
src/util.c
src/vdbemem.c
test/e_expr.test

index d6092d9986acac9320040710f3c0751ad4e2dc66..0bfab54814793e9a556919726b0ed95dff7fd544 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Further\ssimplification,\sperformance\sgain,\sand\ssize\sreduction\sin\nsqlite3FpDecode().
-D 2026-02-21T00:56:11.032
+C Increase\sthe\sprecision\sof\sdouble\s&rarr;\stext\sconversions\sthat\shappen\sin\nsqlite3_column_text(),\sor\ssqlite3_value_text(),\sor\sin\sthe\sCAST()\soperator,\nor\ssimilar,\sso\sthat\sround-tripping\sthe\svalue\sback\sto\sdouble\sresults\sin\nexactly\sthe\ssame\svalue.
+D 2026-02-21T10:57:02.002
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -803,7 +803,7 @@ F src/trigger.c a40440614bdf523090cc07223f4878f7e3c892bcd1a13afe18f90190daa5945d
 F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
-F src/util.c 1aa25fd0e8a9e7e7038dc35576ca084ab1ce305808683ed9fc34c0a911cd7cfe
+F src/util.c 2bff4df366c4af1b50176f7a6b9517782d80bd7a9fd755f132ee6c989001fb24
 F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
 F src/vdbe.c 5328c99dd256ee8132383565a86e253543a85daccfd7477c52f20bac6b385a7f
 F src/vdbe.h 966d0677a540b7ea6549b7c4e1312fc0d830fce3a235a58c801f2cc31cf5ecf9
@@ -811,7 +811,7 @@ F src/vdbeInt.h 42488247a80cd9d300627833c6c85ace067ae5011a99e7614e2358130d62feea
 F src/vdbeapi.c 6cdcbe5c7afa754c998e73d2d5d2805556268362914b952811bdfb9c78a37cf1
 F src/vdbeaux.c 396d38a62a357b807eabae0cae441fc89d2767a57ab08026b7072bf7aa2dd00c
 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
-F src/vdbemem.c bdfda8e65933cfee34aa29c2bfa31fc07609f3d56d147aa8a367a297533d33d1
+F src/vdbemem.c 61b014628c6db12dd10b094b84f3e83ea0f85a1c485891bf0b5f370f3625d4ca
 F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70
 F src/vdbetrace.c 49e689f751505839742f4a243a1a566e57d5c9eaf0d33bbaa26e2de3febf7b41
 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
@@ -1071,7 +1071,7 @@ F test/e_createtable.test 31b9bcb6ac8876bc7ec342d86d9c231a84c62b442093a6651dfd0f
 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
 F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa
 F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
-F test/e_expr.test 0a1e175caddc78b27306647cb4ce2362c55790190f8cdd178b75fd6262eb8f76
+F test/e_expr.test 9bdb347b78b9f4eff9153ea97797facc179a821898588471a70808b4471a69b0
 F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5
 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
@@ -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 b4c378bba582205aa676e45b21ffa17ad6199e2a017ec73cf41a0243f693b589
-R 2ba85f29f79912c10542f94e5fe0f51a
+P 5954f22ceb6b43ed160ec085cd86b66299d8aab3e349a41941a4f1c2eade7457
+R 273816acc4ad445067b918c67e26e2bb
 U drh
-Z 6f74841077f4058908580abdb7a6af5c
+Z 8c81f31c7c681f8cd4928433e40b84e9
 # Remove this line to create a well-formed Fossil manifest.
index 26c7dc2690cbf3b5f42899070ddf5c532ef122e3..6a27d619b073c758077a88ccbcddd68197ee65ed 100644 (file)
@@ -1 +1 @@
-5954f22ceb6b43ed160ec085cd86b66299d8aab3e349a41941a4f1c2eade7457
+ef0049e3ade304f64e1ab97e52e1e21379e4db461f3fa80dac8e544fb90d622f
index ed98fcc59ff4e7a654d113b408b838282197eb0c..3c78c759c23e220ce5e03689ac25d9e2a99e56b7 100644 (file)
@@ -1254,6 +1254,37 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
   z = &zBuf[i+1];  /* z points to the first digit */
   if( iRound>0 && (iRound<n || n>mxRound) ){
     if( iRound>mxRound ) iRound = mxRound;
+    if( iRound==17 ){
+      /* If the precision is exactly 17, which only happens with the "!"
+      ** flag (ex: "%!.17g") then try to reduce the precision if that
+      ** yields text that will round-trip to the original floating-point.
+      ** value.  Thus, for exaple, 49.47 will render as 49.47, rather than
+      ** as 49.469999999999999. */
+      if( z[15]=='9' && z[14]=='9' ){
+        int jj, kk;
+        u64 v2;
+        for(jj=14; jj>0 && z[jj-1]=='9'; jj--){}
+        if( jj==0 ){
+          v2 = 1;
+        }else{
+          v2 = z[0] - '0';
+          for(kk=1; kk<jj; kk++) v2 = (v2*10) + z[kk] - '0';
+          v2++;
+        }
+        if( r==sqlite3Fp10Convert2(v2, exp + n - jj) ){
+          iRound = jj+1;
+        }
+      }else if( p->iDP>=n || (z[15]=='0' && z[14]=='0' && z[13]=='0') ){
+        int jj, kk;
+        u64 v2;
+        for(jj=14; jj>0 && z[jj-1]=='0'; jj--){}
+        v2 = z[0] - '0';
+        for(kk=1; kk<jj; kk++) v2 = (v2*10) + z[kk] - '0';
+        if( r==sqlite3Fp10Convert2(v2, exp + n - jj) ){
+          iRound = jj+1;
+        }
+      }
+    }
     n = iRound;
     if( z[iRound]>='5' ){
       int j = iRound-1;
index 91c45ee08bcf8c5b2399c6a4000249c7829e05b1..48e10146638a28e6f780301e53c9dd63861a4497 100644 (file)
@@ -120,7 +120,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
 #endif
   }else{
     sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
-    sqlite3_str_appendf(&acc, "%!.15g", 
+    sqlite3_str_appendf(&acc, "%!.17g", 
          (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r);
     assert( acc.zText==zBuf && acc.mxAlloc<=0 );
     zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
index 81d2fd172cf8968cf1ee0339389e390b93ace6c0..5c0bfb0c1fcf6cbc29f36ebb86d2669f27d3852b 100644 (file)
@@ -1744,10 +1744,10 @@ do_execsql_test e_expr-32.2.8 {
  integer 9223372036854775807 \
  integer 9223372036854775807 \
  integer 9223372036854775807 \
- real 9.22337203685478e+18 \
- real 9.22337203685478e+18 \
- real 9.22337203685478e+18 \
- real 9.22337203685478e+18 \
+ real 9.2233720368547758e+18 \
+ real 9.2233720368547758e+18 \
+ real 9.2233720368547758e+18 \
+ real 9.2233720368547758e+18 \
  integer -5 \
  integer -5 \
 ]