]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
A cleaner and more robust solution to the floating-point conversion problem
authordrh <>
Sat, 7 Dec 2024 19:12:41 +0000 (19:12 +0000)
committerdrh <>
Sat, 7 Dec 2024 19:12:41 +0000 (19:12 +0000)
originally fixed earlier today.

FossilOrigin-Name: 18b20494ce0d0f8eb87f1157245ebd728d2262f0d1d902a5934f240fc781b4e6

manifest
manifest.uuid
src/util.c

index 6c8af66c363217d77d2e1fce751decbb62ebee6b..e0b7a98abfdf70d92bc1e366a6633f929b57a437 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Increment\sthe\sversion\snumber\sto\s3.47.2
-D 2024-12-07T14:53:43.921
+C A\scleaner\sand\smore\srobust\ssolution\sto\sthe\sfloating-point\sconversion\sproblem\noriginally\sfixed\searlier\stoday.
+D 2024-12-07T19:12:41.603
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -841,7 +841,7 @@ F src/trigger.c 0bb986a5b96047fd597c6aac28588853df56064e576e6b81ba777ef2ccaac461
 F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
 F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
-F src/util.c fde9ad9ce18841a844ce277b4eb4ace4ada7ca4110f9bed5d1d5ce89dabaf957
+F src/util.c 10dc2a3639c9b2393ba44ddd643a9385e22a8aab950160e3a42b76cdc7e3f883
 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
 F src/vdbe.c 1f56a0ae24115c2e37213e77cf79aa3b8c8d0366755707385564f6b8dd83d0fb
 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
@@ -2222,8 +2222,9 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 17537a98cb31ab41f0e02a8403b1480f8d86ddbfc263fd766e73b6b5a7dbba2f
-R fe11019865a741b8876079bd77710e7b
+P 42aa7157f8b549d4321a8811a8223a98f877b60f032f529fd3948dfc0aa54cd7
+Q +351de57f80b73045448c71d3402d877ff5d72418b1f5fc34c8147a04f7c5cb78
+R 99f2d4cc7e69d5c0358c51b93825fdc4
 U drh
-Z 90efad15a3d032dd3857c20292794561
+Z e1fe34756bd989b4f916e0f8d7127934
 # Remove this line to create a well-formed Fossil manifest.
index 36c21da556170c5b2b014e55ff28c8854daa0e4c..9b29617a9a8eca3d5f126984c69895416998c9c5 100644 (file)
@@ -1 +1 @@
-42aa7157f8b549d4321a8811a8223a98f877b60f032f529fd3948dfc0aa54cd7
+18b20494ce0d0f8eb87f1157245ebd728d2262f0d1d902a5934f240fc781b4e6
index 31b05666a01eeb7bad92112e57b3c30c72513532..d553f36c74dccf5b07c6b7be168a3494e8114274 100644 (file)
@@ -539,8 +539,8 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
   int eValid = 1;  /* True exponent is either not used or is well-formed */
   int nDigit = 0;  /* Number of digits processed */
   int eType = 1;   /* 1: pure integer,  2+: fractional  -1 or less: bad UTF16 */
+  u64 s2;          /* round-tripped significand */
   double rr[2];
-  u64 s2;
 
   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
   *pResult = 0.0;   /* Default return value, in case of an error */
@@ -653,14 +653,13 @@ do_atof_calc:
   }
 
   rr[0] = (double)s;
-  if( s<(LARGEST_UINT64-0x7ff) ){
-    s2 = (u64)rr[0];
-#if defined(_MSC_VER) && _MSC_VER<1700
-    if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
-#endif
-    rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
-  }else{
-    s2 = s;
+  s2 = (u64)rr[0];
+  rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
+  if( rr[1]>1e-10*rr[0] ){
+    /* On some floating-point processing units, doing the round
+    ** trip from u64 to double back to u64 can give a wonky value
+    ** when the original u64 is close to LARGEST_UINT64.  If we
+    ** did get an overly large error value, just set it to zero. */
     rr[1] = 0.0;
   }