-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
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
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
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
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.
-51f492b440728151ce64168d5436ba87ca60d84b89408e47c593fa731355afe4
\ No newline at end of file
+9435ed76cd9bb1be02768b3853a2323834f67bda75d3e3f76f6aa7bd0bade3d7
\ No newline at end of file
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
**
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. */
** 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
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);
--- /dev/null
+# 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