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
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to