SQLite

Changes On Branch floating-point-conversions
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch floating-point-conversions Excluding Merge-Ins

This is equivalent to a diff from 699b792c to 0f706acf

2012-06-21
15:22
Merge changes to trunk that ensure that floating point values are exactly preserved on a round-trip through ".dump". (check-in: 4cebd607 user: drh tags: trunk)
15:02
Disable the atof1.test module when compiling on MSVC. (Closed-Leaf check-in: 0f706acf user: drh tags: floating-point-conversions)
2012-06-19
06:35
Add tests to check that the "unicode61" and "icu" tokenizers both identify white-space codepoints outside the ASCII range. (check-in: bfb2d473 user: dan tags: trunk)
04:36
Move variable declaration to fix compilation with MSVC. (check-in: d45f7a01 user: mistachkin tags: floating-point-conversions)
03:11
Improved accuracy on text-to-real and real-to-text conversions. Most conversions now round-trip correctly. Still need to fix some corner cases. (check-in: 8ecffca9 user: drh tags: floating-point-conversions)
00:45
Improved rounding accuracy on text-to-float conversions. (check-in: 699b792c user: drh tags: trunk)
2012-06-18
20:52
Fix a problem with identifying white-space characters outside of the ascii range in the ICU tokenizer. (check-in: 892b7411 user: dan tags: trunk)

Changes to src/func.c.

859
860
861
862
863
864
865
866











867
868
869
870
871
872
873
874
** "NULL".  Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER:











    case SQLITE_FLOAT: {
      sqlite3_result_value(context, argv[0]);
      break;
    }
    case SQLITE_BLOB: {
      char *zText = 0;
      char const *zBlob = sqlite3_value_blob(argv[0]);
      int nBlob = sqlite3_value_bytes(argv[0]);







|
>
>
>
>
>
>
>
>
>
>
>
|







859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
** "NULL".  Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_FLOAT: {
      double r1, r2;
      char zBuf[50];
      r1 = sqlite3_value_double(argv[0]);
      sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
      sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
      if( r1!=r2 ){
        sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
      }
      sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
      break;
    }
    case SQLITE_INTEGER: {
      sqlite3_result_value(context, argv[0]);
      break;
    }
    case SQLITE_BLOB: {
      char *zText = 0;
      char const *zBlob = sqlite3_value_blob(argv[0]);
      int nBlob = sqlite3_value_bytes(argv[0]);

Changes to src/printf.c.

120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
** The counter *cnt is incremented each time.  After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
  int digit;
  LONGDOUBLE_TYPE d;
  if( (*cnt)++ >= 16 ) return '0';

  digit = (int)*val;
  d = digit;
  digit += '0';
  *val = (*val - d)*10.0;
  return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */







|
>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
** The counter *cnt is incremented each time.  After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/
static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
  int digit;
  LONGDOUBLE_TYPE d;
  if( (*cnt)<=0 ) return '0';
  (*cnt)--;
  digit = (int)*val;
  d = digit;
  digit += '0';
  *val = (*val - d)*10.0;
  return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
424
425
426
427
428
429
430

431

432
433

434
435
436
437
438
439
440
        exp = 0;
        if( sqlite3IsNaN((double)realvalue) ){
          bufpt = "NaN";
          length = 3;
          break;
        }
        if( realvalue>0.0 ){

          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }

          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }

          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
          if( exp>350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";







>
|
>
|
|
>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
        exp = 0;
        if( sqlite3IsNaN((double)realvalue) ){
          bufpt = "NaN";
          length = 3;
          break;
        }
        if( realvalue>0.0 ){
          LONGDOUBLE_TYPE scale = 1.0;
          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
          realvalue /= scale;
          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
          if( exp>350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
          if( exp<-4 || exp>precision ){
            xtype = etEXP;
          }else{
            precision = precision - exp;
            xtype = etFLOAT;
          }
        }else{
          flag_rtz = 0;
        }
        if( xtype==etEXP ){
          e2 = 0;
        }else{
          e2 = exp;
        }
        if( e2+precision+width > etBUFSIZE - 15 ){
          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
          if( bufpt==0 ){
            pAccum->mallocFailed = 1;
            return;
          }
        }
        zOut = bufpt;
        nsd = 0;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
        if( prefix ){
          *(bufpt++) = prefix;
        }
        /* Digits prior to the decimal point */
        if( e2<0 ){







|














|







463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
          if( exp<-4 || exp>precision ){
            xtype = etEXP;
          }else{
            precision = precision - exp;
            xtype = etFLOAT;
          }
        }else{
          flag_rtz = flag_altform2;
        }
        if( xtype==etEXP ){
          e2 = 0;
        }else{
          e2 = exp;
        }
        if( e2+precision+width > etBUFSIZE - 15 ){
          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
          if( bufpt==0 ){
            pAccum->mallocFailed = 1;
            return;
          }
        }
        zOut = bufpt;
        nsd = 16 + flag_altform2*10;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
        if( prefix ){
          *(bufpt++) = prefix;
        }
        /* Digits prior to the decimal point */
        if( e2<0 ){

Changes to src/test_config.c.

612
613
614
615
616
617
618















619
620
621
622
623
624
625
  LINKVAR( MAX_DEFAULT_PAGE_SIZE );

  {
    static const int cv_TEMP_STORE = SQLITE_TEMP_STORE;
    Tcl_LinkVar(interp, "TEMP_STORE", (char *)&(cv_TEMP_STORE),
                TCL_LINK_INT | TCL_LINK_READ_ONLY);
  }















}


/*
** Register commands with the TCL interpreter.
*/
int Sqliteconfig_Init(Tcl_Interp *interp){







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  LINKVAR( MAX_DEFAULT_PAGE_SIZE );

  {
    static const int cv_TEMP_STORE = SQLITE_TEMP_STORE;
    Tcl_LinkVar(interp, "TEMP_STORE", (char *)&(cv_TEMP_STORE),
                TCL_LINK_INT | TCL_LINK_READ_ONLY);
  }

#ifdef _MSC_VER
  {
    static const int cv__MSC_VER = 1;
    Tcl_LinkVar(interp, "_MSC_VER", (char *)&(cv__MSC_VER),
                TCL_LINK_INT | TCL_LINK_READ_ONLY);
  }
#endif
#ifdef __GNUC__
  {
    static const int cv___GNUC__ = 1;
    Tcl_LinkVar(interp, "__GNUC__", (char *)&(cv___GNUC__),
                TCL_LINK_INT | TCL_LINK_READ_ONLY);
  }
#endif
}


/*
** Register commands with the TCL interpreter.
*/
int Sqliteconfig_Init(Tcl_Interp *interp){

Changes to test/atof1.test.

10
11
12
13
14
15
16
17





18
19
20
21
22
23





24
25
26
27
28
29
30















31
32
33
34
35
36
#***********************************************************************
# 
# 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








>
>
>
>
>

|
<
|
|
|
>
>
>
>
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#***********************************************************************
# 
# Tests of the sqlite3AtoF() function.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {![info exists __GNUC__]} {
  finish_test
  return
}

expr srand(1)
for {set i 1} {$i<20000} {incr i} {

  set pow [expr {int((rand()-0.5)*100)}]
  set x [expr {pow((rand()-0.5)*2*rand(),$pow)}]
  set xf [format %.32e $x]

  # Verify that text->real conversions get exactly same ieee754 floating-
  # point value in SQLite as they do in TCL.
  #
  do_test atof1-1.$i.1 {
    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}

  # Verify that round-trip real->text->real conversions using the quote()
  # function preserve the bits of the numeric value exactly.
  #
  do_test atof1-1.$i.2 {
    set y [db eval {SELECT $x=CAST(quote($x) AS real)}]
    if {!$y} {
      db eval {SELECT real2hex($x) a, real2hex(CAST(quote($x) AS real)) b} {}
      puts "\nIN:    $a $xf"
      puts [format {QUOTE: %16s %s} {} [db eval {SELECT quote($x)}]]
      db eval {SELECT CAST(quote($x) AS real) c} {}
      puts "OUT:   $b [format %.32e $c]"
    }
    set y
  } {1}
}


finish_test

Changes to test/date.test.

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
datetest 2.51 {datetime('2003-10-22 12:24','nonsense')} NULL

datetest 3.1 {strftime('%d','2003-10-31 12:34:56.432')} 31
datetest 3.2.1 {strftime('pre%fpost','2003-10-31 12:34:56.432')} pre56.432post
datetest 3.2.2 {strftime('%f','2003-10-31 12:34:59.9999999')} 59.999
datetest 3.3 {strftime('%H','2003-10-31 12:34:56.432')} 12
datetest 3.4 {strftime('%j','2003-10-31 12:34:56.432')} 304
datetest 3.5 {strftime('%J','2003-10-31 12:34:56.432')} 2452944.02426426
datetest 3.6 {strftime('%m','2003-10-31 12:34:56.432')} 10
datetest 3.7 {strftime('%M','2003-10-31 12:34:56.432')} 34
datetest 3.8.1 {strftime('%s','2003-10-31 12:34:56.432')} 1067603696
datetest 3.8.2 {strftime('%s','2038-01-19 03:14:07')} 2147483647
datetest 3.8.3 {strftime('%s','2038-01-19 03:14:08')} 2147483648
datetest 3.8.4 {strftime('%s','2201-04-09 12:00:00')} 7298164800
datetest 3.8.5 {strftime('%s','9999-12-31 23:59:59')} 253402300799







|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
datetest 2.51 {datetime('2003-10-22 12:24','nonsense')} NULL

datetest 3.1 {strftime('%d','2003-10-31 12:34:56.432')} 31
datetest 3.2.1 {strftime('pre%fpost','2003-10-31 12:34:56.432')} pre56.432post
datetest 3.2.2 {strftime('%f','2003-10-31 12:34:59.9999999')} 59.999
datetest 3.3 {strftime('%H','2003-10-31 12:34:56.432')} 12
datetest 3.4 {strftime('%j','2003-10-31 12:34:56.432')} 304
datetest 3.5 {strftime('%J','2003-10-31 12:34:56.432')} 2452944.024264259
datetest 3.6 {strftime('%m','2003-10-31 12:34:56.432')} 10
datetest 3.7 {strftime('%M','2003-10-31 12:34:56.432')} 34
datetest 3.8.1 {strftime('%s','2003-10-31 12:34:56.432')} 1067603696
datetest 3.8.2 {strftime('%s','2038-01-19 03:14:07')} 2147483647
datetest 3.8.3 {strftime('%s','2038-01-19 03:14:08')} 2147483648
datetest 3.8.4 {strftime('%s','2201-04-09 12:00:00')} 7298164800
datetest 3.8.5 {strftime('%s','9999-12-31 23:59:59')} 253402300799

Changes to test/func.test.

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  do_test func-4.36 {
    execsql {SELECT round(99999999999994.5);}
  } {99999999999995.0}
  do_test func-4.37 {
    execsql {SELECT round(9999999999999.55,1);}
  } {9999999999999.6}
  do_test func-4.38 {
    execsql {SELECT round(9999999999999.555,2);}
  } {9999999999999.56}
}

# Test the upper() and lower() functions
#
do_test func-5.1 {
  execsql {SELECT upper(t1) FROM tbl1}







|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  do_test func-4.36 {
    execsql {SELECT round(99999999999994.5);}
  } {99999999999995.0}
  do_test func-4.37 {
    execsql {SELECT round(9999999999999.55,1);}
  } {9999999999999.6}
  do_test func-4.38 {
    execsql {SELECT round(9999999999999.556,2);}
  } {9999999999999.56}
}

# Test the upper() and lower() functions
#
do_test func-5.1 {
  execsql {SELECT upper(t1) FROM tbl1}