]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
New test cases for floating-point conversions.
authordrh <>
Mon, 3 Jul 2023 12:58:18 +0000 (12:58 +0000)
committerdrh <>
Mon, 3 Jul 2023 12:58:18 +0000 (12:58 +0000)
FossilOrigin-Name: 9435ed76cd9bb1be02768b3853a2323834f67bda75d3e3f76f6aa7bd0bade3d7

manifest
manifest.uuid
src/test1.c
src/util.c
test/fpconv1.test [new file with mode: 0644]

index fd10ee48998cbeba328b573b5d4e8a4958d7bd1d..0c46f90368ab6a6e25e035073503fbc4aac5f3a3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Use\sDekker\sdouble-precision\sfloating\spoint\sto\sdo\sthe\svalue\snormalization\nstep\sin\ssqlite3FpDecode()\sfor\ssystems\son\swhich\s"long\sdouble"\sis\s8\sbytes\sor\nless.
-D 2023-07-03T11:44:15.056
+C New\stest\scases\sfor\sfloating-point\sconversions.
+D 2023-07-03T12:58:18.851
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -647,7 +647,7 @@ F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee
 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd
-F src/test1.c 64b8462099618a6243f63ba701eea8913046cd7377a7a77a7e3a0ada42219275
+F src/test1.c ac81daaee5135d210f926e7d1501d6065d396decac57af94083e677cf7e175bd
 F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef
 F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e
 F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
@@ -705,7 +705,7 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
 F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
 F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
-F src/util.c 44855f67ac96b546b77b6c2ad128d1e28a56c495038cdda3cae25b8407442f3c
+F src/util.c 97f9a7a1a22db23984ca3ced12ed666327c17beeaf8481c3325a0c74369060dc
 F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
 F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
 F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
@@ -1014,6 +1014,7 @@ F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84
 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
 F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c
 F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4
+F test/fpconv1.test d5d8aa0c427533006c112fb1957cdd1ea68c1d0709470dabb9ca02c2e4c06ad8
 F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
 F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
 F test/fts3_common.tcl dffad248f9ce090800e272017d2898005c28ee6314fc1dd5550643a02666907a
@@ -2041,9 +2042,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ce06982f880339cf46704e95c907249827c3e44af2b9420005200ca8abd3f371 40285d631072b79aba39cc20d4b217bdf0069f29ac9902cb97dec28d3e4cde11
-R 8a559af6860b1623fc9d9f5fb9393b11
-T +closed 40285d631072b79aba39cc20d4b217bdf0069f29ac9902cb97dec28d3e4cde11
+P 51f492b440728151ce64168d5436ba87ca60d84b89408e47c593fa731355afe4
+R 610c019b12f01dbb4053eb803e9a81bd
 U drh
-Z 98f04f31ed955532d376706d5d138150
+Z 391291e9df52bc2766a8acd3f9c94d15
 # Remove this line to create a well-formed Fossil manifest.
index b3071eda1b7cfc43838b05e325e38673235ddc81..f201e504af7bad468ab2645117974256bbf541e1 100644 (file)
@@ -1 +1 @@
-51f492b440728151ce64168d5436ba87ca60d84b89408e47c593fa731355afe4
\ No newline at end of file
+9435ed76cd9bb1be02768b3853a2323834f67bda75d3e3f76f6aa7bd0bade3d7
\ No newline at end of file
index c77aff2ed25522e66327b662a49ab21f3365dd6d..013adcbcb0ec761823fbaec467fb458cd54aea80 100644 (file)
@@ -991,6 +991,46 @@ static void intrealFunction(
   sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);
 }
 
+/*
+** SQL function:  strtod(X)
+**
+** Use the C-library strtod() function to convert string X into a double.
+** Used for comparing the accuracy of SQLite's internal text-to-float conversion
+** routines against the C-library.
+*/
+static void shellStrtod(
+  sqlite3_context *pCtx,
+  int nVal,
+  sqlite3_value **apVal
+){
+  char *z = (char*)sqlite3_value_text(apVal[0]);
+  UNUSED_PARAMETER(nVal);
+  if( z==0 ) return;
+  sqlite3_result_double(pCtx, strtod(z,0));
+}
+
+/*
+** SQL function:  dtostr(X)
+**
+** Use the C-library printf() function to convert real value X into a string.
+** Used for comparing the accuracy of SQLite's internal float-to-text conversion
+** routines against the C-library.
+*/
+static void shellDtostr(
+  sqlite3_context *pCtx,
+  int nVal,
+  sqlite3_value **apVal
+){
+  double r = sqlite3_value_double(apVal[0]);
+  int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
+  char z[400];
+  if( n<1 ) n = 1;
+  if( n>350 ) n = 350;
+  sprintf(z, "%#+.*e", n, r);
+  sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
+}
+
+
 /*
 ** Usage:  sqlite3_create_function DB
 **
@@ -1063,6 +1103,27 @@ static int SQLITE_TCLAPI test_create_function(
           0, intrealFunction, 0, 0);
   }
 
+  /* Functions strtod() and dtostr() work as in the shell.  These routines
+  ** use the standard C library to convert between floating point and
+  ** text.  This is used to compare SQLite's internal conversion routines
+  ** against the standard library conversion routines.
+  **
+  ** Both routines copy/pasted from the shell.c.in implementation
+  ** on 2023-07-03.
+  */
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "strtod", 1, SQLITE_UTF8, 0,
+                                 shellStrtod, 0, 0);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "dtostr", 1, SQLITE_UTF8, 0,
+                                 shellDtostr, 0, 0);
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3_create_function(db, "dtostr", 2, SQLITE_UTF8, 0,
+                                 shellDtostr, 0, 0);
+  }
+
 #ifndef SQLITE_OMIT_UTF16
   /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
   ** because it is not tested anywhere else. */
index cf4745bd0ba210dd64f246f0dfca13a405cad6a6..7642a29bca1201b16dcb39903347febc554e3149 100644 (file)
@@ -934,7 +934,7 @@ int sqlite3Atoi(const char *z){
 **   T. J. Dekker, "A Floating-Point Technique for Extending the
 **   Available Precision".  1971-07-26.
 */
-static void mul2(
+static void dekkerMul2(
   double x,  double xx,
   double y,  double yy,
   double *z, double *zz
@@ -1025,28 +1025,28 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
     if( r>1.84e+19 ){
       while( r>1.84e+119 ){
         exp += 100;
-        mul2(r, rr, 1.0e-100, -1.99918998026028836196e-117, &r, &rr);
+        dekkerMul2(r, rr, 1.0e-100, -1.99918998026028836196e-117, &r, &rr);
       }
       while( r>1.84e+29 ){
         exp += 10;
-        mul2(r,rr, 1.0e-10, -3.6432197315497741579e-27, &r, &rr);
+        dekkerMul2(r,rr, 1.0e-10, -3.6432197315497741579e-27, &r, &rr);
       }
       while( r>1.84e+19 ){
         exp += 1;
-        mul2(r,rr, 1.0e-01, -5.5511151231257827021e-18, &r, &rr);
+        dekkerMul2(r,rr, 1.0e-01, -5.5511151231257827021e-18, &r, &rr);
       }
     }else{
       while( r<1.84e-82  ){
         exp -= 100;
-        mul2(r, rr, 1.0e+100, -1.5902891109759918046e+83, &r, &rr);
+        dekkerMul2(r, rr, 1.0e+100, -1.5902891109759918046e+83, &r, &rr);
       }
       while( r<1.84e+08  ){
         exp -= 10;
-        mul2(r, rr, 1.0e+10, 0.0, &r, &rr);
+        dekkerMul2(r, rr, 1.0e+10, 0.0, &r, &rr);
       }
       while( r<1.84e+18  ){
         exp -= 1;
-        mul2(r, rr, 1.0e+01, 0.0, &r, &rr);
+        dekkerMul2(r, rr, 1.0e+01, 0.0, &r, &rr);
       }
     }
     v = (u64)(r)+(u64)(rr);
diff --git a/test/fpconv1.test b/test/fpconv1.test
new file mode 100644 (file)
index 0000000..195fdf9
--- /dev/null
@@ -0,0 +1,44 @@
+# 2023-07-03
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# 
+# This file contains a test that attempts to verify the claim that the
+# floatpoint-to-text conversion routines built into SQLite maintain at
+# least 15 significant digits of accuracy.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+if {[catch {load_static_extension db decimal} error]} {
+  puts "Skipping decimal tests, hit load error: $error"
+  finish_test; return
+}
+
+sqlite3_create_function db
+do_execsql_test fpconv1-1.0 {
+  WITH RECURSIVE
+       /* Number of random floating-point values to try.
+       ** On a circa 2016 x64 linux box, this test runs at
+       ** about 80000 cases per second  -------------------vvvvvv */
+    c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100000),
+    fp(y) AS MATERIALIZED (
+       SELECT CAST( format('%+d.%019d0e%+03d',
+                           random()%10,abs(random()),random()%200) AS real)
+        FROM c
+    )
+  SELECT y FROM fp
+   WHERE -log10(abs(decimal_sub(dtostr(y,24),format('%!.24e',y))/y))<15.0;
+                     /* Number of digits of accuracy required -------^^^^ */
+} {}
+#  ^---- Expect a empty set as the result.  The output is all tested numbers
+#        that fail to preserve at least 15 significant digits of accuracy.
+
+finish_test