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 | ** "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]) ){ | | > > > > > > > > > > > | | 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 | ** 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; | | > | 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 | exp = 0; if( sqlite3IsNaN((double)realvalue) ){ bufpt = "NaN"; length = 3; break; } if( realvalue>0.0 ){ | > | > | | > | 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 | if( exp<-4 || exp>precision ){ xtype = etEXP; }else{ precision = precision - exp; xtype = etFLOAT; } }else{ | | | | 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 | #*********************************************************************** # # Tests of the sqlite3AtoF() function. # set testdir [file dirname $argv0] source $testdir/tester.tcl expr srand(1) | > > > > > | < | | | > > > > > > > > > > > > > > > > > > > > | 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 | 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 | | | 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 | 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 { | | | 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} |
︙ | ︙ |