Hi all,
Here is a summary of my investigations related to the "99990.1 case".
[FYI, 8674146.01 is another example]
The short (and censured :-) version: WTF!? That's just insane!!!
Look at this (sqlite3.c compiled only ONE TIME with default options):
[---
test.js:
var db = new SQLite();
db.exec("select 99990.1", function(r){writeln(r)});
---
JSDB under GDB:
(gdb) break sqlite3.c:19917
Breakpoint 1 at 0x57d82d: file sqlite3.c, line 19917.
(gdb) run
Starting program: R:\jsdb/jsdb.exe test.js
[New Thread 21228.0x52f8]
Breakpoint 1, sqlite3VXPrintf (pAccum=0x22e184, useExtended=0,
fmt=0x65323d "g", ap=0x22e1f4 "") at sqlite3.c:19917
19917 realvalue /= 10.0;
(gdb) print ((unsigned char *) &realvalue)[0]@13
$1 = "\000ÐÌÌÌ\fKÃ\017@\000\000Ú"
(gdb) n
19918 exp++;
(gdb) print ((unsigned char *) &realvalue)[0]@13
$2 = "\000Ø£p=\n<o\f@\000\000Ú"
(gdb) del 1
(gdb) cont
Continuing.
99990.1=99990.1
----
SQLite-shell through GDB:
(gdb) break sqlite3.c:19917
Breakpoint 1 at 0x4063b1: file sqlite3.c, line 19917.
(gdb) run
Starting program: R:\jsdb\sqlite/SQLite.exe NUL "select 99990.1;"
[New Thread 21300.0x5318]
Breakpoint 1, sqlite3VXPrintf (pAccum=0x22f724, useExtended=0,
fmt=0x48351d "g", ap=0x22f794 "") at sqlite3.c:19917
19917 realvalue /= 10.0;
(gdb) print ((unsigned char *) &realvalue)[0]@13
$1 = "\000ÐÌÌÌ\fKÃ\017@\000\000Ú"
(gdb) n
19918 exp++;
(gdb) print ((unsigned char *) &realvalue)[0]@13
$2 = "sÙ£p=\n<o\f@\000\000Ú"
(gdb) del 1
(gdb) cont
Continuing.
99990.1
As you can see, the "realvalue" variable has byte-to-byte (sizeof(long
double)=12 here) identical values BEFORE executing line 19917.
The 2 less significant bytes diverge after the division by 10 - same behaviour
with the original op. "realvalue*=0.1".
Same behaviour? Not exactly... In this case, the rounding error is different
and final (post-processed) outputs are identical!!!!!
So here are (maybe) 2 simple alternatives to Keith's patch:
1) operation substitution
19909,19911c
while( realvalue>=1e32 && exp<=350 ){ realvalue /= 1e32; exp+=32; }
while( realvalue>=1e8 && exp<=350 ){ realvalue /= 1e8; exp+=8; }
while( realvalue>=10.0 && exp<=350 ){ realvalue /= 10.0; exp++; }
2) decreasing the max number of required mult.
19910,19911c
if( realvalue>=1e16 && exp<=350 ){ realvalue *= 1e-16; exp+=16; }
if( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
if( realvalue>=1e4 && exp<=350 ){ realvalue *= 1e-4; exp+=4; }
if( realvalue>=1e2 && exp<=350 ){ realvalue *= 1e-2; exp+=2; }
if( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
I trust you guys, for fixing SQLite smoothly.
A big thank you for your patch Keith.
Keep up the very good work!!!!
Etienne
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users