]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved rounding accuracy on test-to-float conversions.
authordrh <drh@noemail.net>
Tue, 19 Jun 2012 00:45:16 +0000 (00:45 +0000)
committerdrh <drh@noemail.net>
Tue, 19 Jun 2012 00:45:16 +0000 (00:45 +0000)
FossilOrigin-Name: 699b792c6a0e989994549959b11ec1bfad8bbd92

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

index b57416185b2ac82157ca55164a7023890f2e427d..9606896e108cbfba25979a1a0ba1e435b283a30b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\swith\sidentifying\swhite-space\scharacters\soutside\sof\sthe\sascii\srange\sin\sthe\sICU\stokenizer.
-D 2012-06-18T20:52:32.200
+C Improved\srounding\saccuracy\son\stest-to-float\sconversions.
+D 2012-06-19T00:45:16.776
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in d17fddaa4e81f93a7c9c7c0808aacb3fc95f79f4
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -203,7 +203,7 @@ F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
 F src/test_config.c 4f7b8030287d62fe56a1d99e68b41760feae381a
 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
-F src/test_func.c 090f2c3339e85c2c964435f99aed6f3da9d59525
+F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
 F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
 F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
@@ -237,7 +237,7 @@ F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
 F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
 F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
 F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
-F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3
+F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
 F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
 F src/vdbe.c f5ad3c06dc3fe647097065829c013f3f1b9eadca
 F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
@@ -274,6 +274,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
 F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
 F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c
+F test/atof1.test 1f6dc0f47f6697e32fa51dd154412e1172984928
 F test/attach.test 0d112b7713611fdf0340260192749737135fda5f
 F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966
 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e
@@ -1005,7 +1006,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 0c2fb18d25217ada7e75dcab8b342bbc632875d8
-R de31ab49b2137fc2f97d1253270053d5
-U dan
-Z 2c0f1a3c7e342f99735e428af302d9d8
+P 892b74116a3b23268895b96433d18ef00c1433d8
+R f92cf3b5f19c2cdf0a1f4043259e76e0
+U drh
+Z 37917877b4f7a2aac8f4f47ec8031274
index 75492d0b4994f9d2727d34dc2746b0e53e7f335d..9a76fd8178458b09d92aa9f6760893d1cdcce44d 100644 (file)
@@ -1 +1 @@
-892b74116a3b23268895b96433d18ef00c1433d8
\ No newline at end of file
+699b792c6a0e989994549959b11ec1bfad8bbd92
\ No newline at end of file
index c4fe351cb9d615e7ed533968840637dc253ed097..6f9bb03dc88a21d658bf9999baf66dc1d52ebc54 100644 (file)
@@ -422,6 +422,43 @@ static void testHexToUtf16le(
 }
 #endif
 
+/*
+** SQL function:   real2hex(X)
+**
+** If argument X is a real number, then convert it into a string which is
+** the big-endian hexadecimal representation of the ieee754 encoding of
+** that number.  If X is not a real number, return NULL.
+*/
+static void real2hex(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  union {
+    sqlite3_uint64 i;
+    double r;
+    unsigned char x[8];
+  } v;
+  char zOut[20];
+  int i;
+  int bigEndian;
+  v.i = 1;
+  bigEndian = v.x[0]==0;
+  v.r = sqlite3_value_double(argv[0]);
+  for(i=0; i<8; i++){
+    if( bigEndian ){
+      zOut[i*2]   = "0123456789abcdef"[v.x[i]>>4];
+      zOut[i*2+1] = "0123456789abcdef"[v.x[i]&0xf];
+    }else{
+      zOut[14-i*2]   = "0123456789abcdef"[v.x[i]>>4];
+      zOut[14-i*2+1] = "0123456789abcdef"[v.x[i]&0xf];
+    }
+  }
+  zOut[16] = 0;
+  sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT);
+}
+
+
 static int registerTestFunctions(sqlite3 *db){
   static const struct {
      char *zName;
@@ -444,6 +481,7 @@ static int registerTestFunctions(sqlite3 *db){
     { "test_eval",             1, SQLITE_UTF8, test_eval},
     { "test_isolation",        2, SQLITE_UTF8, test_isolation},
     { "test_counter",          1, SQLITE_UTF8, counterFunc},
+    { "real2hex",              1, SQLITE_UTF8, real2hex},
   };
   int i;
 
index dd3b08ae464c3b7fd8505fe7ac9751dc833a001b..5cf8ebacb5db2d8489e192498d9d627be9201cbb 100644 (file)
@@ -371,7 +371,7 @@ do_atof_calc:
     /* if exponent, scale significand as appropriate
     ** and store in result. */
     if( e ){
-      double scale = 1.0;
+      LONGDOUBLE_TYPE scale = 1.0;
       /* attempt to handle extremely small/large numbers better */
       if( e>307 && e<342 ){
         while( e%308 ) { scale *= 1.0e+1; e -= 1; }
diff --git a/test/atof1.test b/test/atof1.test
new file mode 100644 (file)
index 0000000..dff5e2a
--- /dev/null
@@ -0,0 +1,36 @@
+# 2012 June 18
+#
+# 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.
+#
+#***********************************************************************
+# 
+# Tests of the sqlite3AtoF() function.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+expr srand(1)
+for {set i 1} {$i<10000} {incr i} {
+  do_test 1.$i {
+    set pow [expr {int((rand()-0.5)*100)}]
+    set x [expr {pow((rand()-0.5)*2*rand(),$pow)}]
+    set xf [format %.45e $x]
+    set y [db eval "SELECT $xf=\$x"]
+    if {!$y} {
+      puts -nonewline \173[db eval "SELECT real2hex($xf), real2hex(\$x)"]\175
+      db eval "SELECT $xf+0.0 AS a, \$x AS b" {
+        puts [format "\n%.60e\n%.60e\n%.60e" $x $a $b]
+      }
+    }
+    set y
+  } {1}
+}
+
+
+finish_test