Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | better handling of exponential notation (CVS 145) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ea0e32828f5643eeb00b216a287d14f4 |
User & Date: | drh 2000-09-14 01:21:10.000 |
Context
2000-09-14
| ||
01:25 | Version 1.0.5 (CVS 495) (check-in: 84839d8764 user: drh tags: trunk) | |
01:21 | better handling of exponential notation (CVS 145) (check-in: ea0e32828f user: drh tags: trunk) | |
2000-08-28
| ||
16:25 | Version 1.0.4 (CVS 496) (check-in: 92346e003e user: drh tags: trunk) | |
Changes
Changes to VERSION.
|
| | | 1 | 1.0.5 |
Changes to src/util.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.15 2000/09/14 01:21:10 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> #ifdef MEMORY_DEBUG |
︙ | ︙ | |||
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | } case 5: { result = cb - ca; }; } return result; } /* This comparison routine is what we use for comparison operations ** in an SQL expression. (Ex: name<'Hello' or value<5). Compare two ** strings. Use case only as a tie-breaker. Numbers compare in ** numerical order. */ int sqliteCompare(const char *atext, const char *btext){ int result; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 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 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | } case 5: { result = cb - ca; }; } return result; } /* ** Do a comparison of pure numerics. If either string is not a pure ** numeric, then return 0. Otherwise return 1 and set *pResult to be ** negative, zero or positive if the first string are numerially less than ** equal to, or greater than the second. */ static int privateCompareNum(const char *a, const char *b, int *pResult){ char *endPtr; double rA, rB; int isNumA, isNumB; if( isdigit(*a) || ((*a=='-' || *a=='+') && isdigit(a[1])) ){ rA = strtod(a, &endPtr); isNumA = *endPtr==0; }else{ isNumA = 0; } if( isdigit(*b) || ((*b=='-' || *b=='+') && isdigit(b[1])) ){ rB = strtod(b, &endPtr); isNumB = *endPtr==0; }else{ isNumB = 0; } if( isNumB==0 && isNumA==0 ) return 0; if( isNumA!=isNumB ){ *pResult = isNumA - isNumB; }else if( rA<rB ){ *pResult = -1; }else if( rA>rB ){ *pResult = 1; }else{ *pResult = 0; } return 1; } /* This comparison routine is what we use for comparison operations ** in an SQL expression. (Ex: name<'Hello' or value<5). Compare two ** strings. Use case only as a tie-breaker. Numbers compare in ** numerical order. */ int sqliteCompare(const char *atext, const char *btext){ int result; if( !privateCompareNum(atext, btext, &result) || result==0 ){ result = privateStrCmp(atext, btext, 0); if( result==0 ) result = privateStrCmp(atext, btext, 1); } return result; } /* ** If you compile just this one file with the -DTEST_COMPARE=1 option, ** it generates a program to test the comparisons routines. */ #ifdef TEST_COMPARE #include <stdlib.h> #include <stdio.h> int sortCmp(const char **a, const char **b){ return sqliteCompare(*a, *b); } int main(int argc, char **argv){ int i, j, k, n, cnt; static char *azStr[] = { "abc", "aBc", "abcd", "aBcd", "123", "124", "1234", "-123", "-124", "-1234", "+124", "123.45", "123.456", "123.46", "-123.45", "-123.46", "-123.456", "x9", "x10", "x-9", "x-10", "X9", "X10", "1.234e+02", "+123", "1.23E2", "1.2345e+2", "-1.2345e2", "+w" }; n = sizeof(azStr)/sizeof(azStr[0]); qsort(azStr, n, sizeof(azStr[0]), sortCmp); for(i=0; i<n; i++){ printf("%s\n", azStr[i]); } printf("Sanity1..."); fflush(stdout); cnt = 0; for(i=0; i<n-1; i++){ char *a = azStr[i]; for(j=i+1; j<n; j++){ char *b = azStr[j]; if( sqliteCompare(a,b) != -sqliteCompare(b,a) ){ printf("Failed! \"%s\" vs \"%s\"\n", a, b); i = j = n; } cnt++; } } if( i<n ){ printf(" OK (%d)\n", cnt); } printf("Sanity2..."); fflush(stdout); cnt = 0; for(i=0; i<n; i++){ char *a = azStr[i]; for(j=0; j<n; j++){ char *b = azStr[j]; for(k=0; k<n; k++){ char *c = azStr[k]; int x1, x2, x3, success; x1 = sqliteCompare(a,b); x2 = sqliteCompare(b,c); x3 = sqliteCompare(a,c); if( x1==0 ){ success = x2==x3; }else if( x1<0 ){ success = (x2<=0 && x3<=0) || x2>0; }else{ success = (x2>=0 && x3>=0) || x2<0; } if( !success ){ printf("Failed! \"%s\" vs \"%s\" vs \"%s\"\n", a, b, c); i = j = k = n+1; } cnt++; } } } if( i<n+1 ){ printf(" OK (%d)\n", cnt); } return 0; } #endif /* ** This routine is used for sorting. Each key is a list of one or more |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | ** inplicit conversion from one type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ** inplicit conversion from one type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.41 2000/09/14 01:21:10 drh Exp $ */ #include "sqliteInt.h" #include <unistd.h> /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance |
︙ | ︙ | |||
543 544 545 546 547 548 549 | */ #define Stringify(P,I) \ ((P->aStack[I].flags & STK_Str)==0 ? hardStringify(P,I) : 0) static int hardStringify(Vdbe *p, int i){ char zBuf[30]; int fg = p->aStack[i].flags; if( fg & STK_Real ){ | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | */ #define Stringify(P,I) \ ((P->aStack[I].flags & STK_Str)==0 ? hardStringify(P,I) : 0) static int hardStringify(Vdbe *p, int i){ char zBuf[30]; int fg = p->aStack[i].flags; if( fg & STK_Real ){ sprintf(zBuf,"%.15g",p->aStack[i].r); }else if( fg & STK_Int ){ sprintf(zBuf,"%d",p->aStack[i].i); }else{ p->zStack[i] = ""; p->aStack[i].n = 1; p->aStack[i].flags |= STK_Str; return 0; |
︙ | ︙ |
Changes to test/expr.test.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # drh@hwaci.com # http://www.hwaci.com/drh/ # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # drh@hwaci.com # http://www.hwaci.com/drh/ # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # # $Id: expr.test,v 1.9 2000/09/14 01:21:11 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a table to work with. # execsql {CREATE TABLE test1(i1 int, i2 int, r1 real, r2 real, t1 text, t2 text)} |
︙ | ︙ | |||
76 77 78 79 80 81 82 | test_expr expr-1.35 {i1=1, i2=2} {i1-i2=-1} {1} test_expr expr-1.36 {i1=1, i2=0} {not i1} {0} test_expr expr-1.37 {i1=1, i2=NULL} {not i2} {1} test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782 | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | test_expr expr-1.35 {i1=1, i2=2} {i1-i2=-1} {1} test_expr expr-1.36 {i1=1, i2=0} {not i1} {0} test_expr expr-1.37 {i1=1, i2=NULL} {not i2} {1} test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 test_expr expr-2.3 {r1=1.23, r2=2.34} {r1*r2} 2.8782 test_expr expr-2.4 {r1=1.23, r2=2.34} {r1/r2} 0.525641025641026 test_expr expr-2.5 {r1=1.23, r2=2.34} {r2/r1} 1.90243902439024 test_expr expr-2.6 {r1=1.23, r2=2.34} {r2<r1} 0 test_expr expr-2.7 {r1=1.23, r2=2.34} {r2<=r1} 0 test_expr expr-2.8 {r1=1.23, r2=2.34} {r2>r1} 1 test_expr expr-2.9 {r1=1.23, r2=2.34} {r2>=r1} 1 test_expr expr-2.10 {r1=1.23, r2=2.34} {r2!=r1} 1 test_expr expr-2.11 {r1=1.23, r2=2.34} {r2=r1} 0 test_expr expr-2.12 {r1=1.23, r2=2.34} {r2<>r1} 1 |
︙ | ︙ |
Changes to www/changes.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2000 Aug 28 (Version 1.0.4)} { <li>Added functions <b>length()</b> and <b>substr()</b>.</li> <li>Fix a bug in the <b>sqlite</b> shell program that was causing a coredump when the output mode was "column" and the first row of data contained a NULL.</li> } | > > > > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2000 Sep 13 (Version 1.0.5)} { <li>Changed the print format for floating point values from "%g" to "%.15g". </li> <li>Changed the comparison function so that numbers in exponential notation (ex: 1.234e+05) sort in numerical order.</li> } chng {2000 Aug 28 (Version 1.0.4)} { <li>Added functions <b>length()</b> and <b>substr()</b>.</li> <li>Fix a bug in the <b>sqlite</b> shell program that was causing a coredump when the output mode was "column" and the first row of data contained a NULL.</li> } |
︙ | ︙ |