From: shane Date: Fri, 21 Aug 2009 02:13:14 +0000 (+0000) Subject: Updated sqlite3AtoF() that performs slightly better with GCC, and significantly bette... X-Git-Tag: fts3-refactor~237 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6085f5e0a0d81869b6aa12d4d763c6ee8e7a285c;p=thirdparty%2Fsqlite.git Updated sqlite3AtoF() that performs slightly better with GCC, and significantly better with MSVC. FossilOrigin-Name: f084f5a8ba850de627ca8e9de6c81ab1ad9b7a1b --- diff --git a/manifest b/manifest index 1f242c8181..7d2418f3e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sfor\stest_init.c\sfor\sconfigure\sand\sother\sconsistency\schanges. -D 2009-08-21T02:07:09 +C Updated\ssqlite3AtoF()\sthat\sperforms\sslightly\sbetter\swith\sGCC,\sand\ssignificantly\sbetter\swith\sMSVC. +D 2009-08-21T02:13:14 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 73ddeec9dd10b85876c5c2ce1fdce627e1dcc7f8 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -203,7 +203,7 @@ F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b F src/trigger.c 9bc5278d509d81ff0f9b52f0ce7239563d188e32 F src/update.c 4da327f706c0d0dfedf4d92154b1b5688bdea0ac F src/utf.c 3ca2c9461b8e942c68da28bfccd448663f536a6f -F src/util.c c2416f60ae704a8c4990e4909aa810f90cbffa07 +F src/util.c efb5f8e533d4beef545cf765cab5f7920b4c75f9 F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0 F src/vdbe.c 464e2e30b1287554a23cdaa0b6b010a9dcb5eb29 F src/vdbe.h 457b6c70f02885cec1f5225b5e6441d067b55d3f @@ -490,7 +490,7 @@ F test/misc7.test c5f4e6a82e04e71820c0f9f64f6733f04c8ae0ae F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33 F test/mutex1.test 5b71777fc127509cd257910c8db799de557a02de F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 -F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a +F test/nan.test cf555724e5a26aed2296a3f2637feee9f728cd81 F test/notify1.test 8433bc74bd952fb8a6e3f8d7a4c2b28dfd69e310 F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82 @@ -747,7 +747,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P d30ceeb8b303e2ebfab2855beb973da606a97fa9 -R b6c943de06895c49e2a370130875c453 +P 3ba316e9a32de406a4390fb3f52fccb48da4da30 +R bbc63800e202da4f72f0395afa840353 U shane -Z 2aa9a5ab5a904bd727c216c0a651a78e +Z aada4480e610c2af2b7cf949ce420cab diff --git a/manifest.uuid b/manifest.uuid index b69532a843..5e57603799 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ba316e9a32de406a4390fb3f52fccb48da4da30 \ No newline at end of file +f084f5a8ba850de627ca8e9de6c81ab1ad9b7a1b \ No newline at end of file diff --git a/src/util.c b/src/util.c index ab757eba69..ef291b94b3 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,6 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.262 2009/07/28 16:44:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -273,7 +272,7 @@ int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ } /* -** The string z[] is an ascii representation of a real number. +** The string z[] is an ASCII representation of a real number. ** Convert this string to a double. ** ** This routine assumes that z[] really is a valid number. If it @@ -286,70 +285,111 @@ int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ */ int sqlite3AtoF(const char *z, double *pResult){ #ifndef SQLITE_OMIT_FLOATING_POINT - int sign = 1; const char *zBegin = z; - LONGDOUBLE_TYPE v1 = 0.0; - int nSignificant = 0; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + double result; + int nDigits = 0; + + /* skip leading spaces */ while( sqlite3Isspace(*z) ) z++; + /* get sign of significand */ if( *z=='-' ){ sign = -1; z++; }else if( *z=='+' ){ z++; } - while( z[0]=='0' ){ - z++; - } - while( sqlite3Isdigit(*z) ){ - v1 = v1*10.0 + (*z - '0'); - z++; - nSignificant++; + /* skip leading zeroes */ + while( z[0]=='0' ) z++, nDigits++; + + /* copy max significant digits to significand */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++; } + /* skip non-significant significand digits + ** (increase exponent by d to shift decimal left) */ + while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; + + /* if decimal point is present */ if( *z=='.' ){ - LONGDOUBLE_TYPE divisor = 1.0; z++; - if( nSignificant==0 ){ - while( z[0]=='0' ){ - divisor *= 10.0; - z++; - } - } - while( sqlite3Isdigit(*z) ){ - if( nSignificant<18 ){ - v1 = v1*10.0 + (*z - '0'); - divisor *= 10.0; - nSignificant++; - } - z++; + /* copy digits from after decimal to significand + ** (decrease exponent by d to shift decimal right) */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++, d--; } - v1 /= divisor; + /* skip non-significant digits */ + while( sqlite3Isdigit(*z) ) z++, nDigits++; } + + /* if exponent is present */ if( *z=='e' || *z=='E' ){ - int esign = 1; - int eval = 0; - LONGDOUBLE_TYPE scale = 1.0; z++; + /* get sign of exponent */ if( *z=='-' ){ esign = -1; z++; }else if( *z=='+' ){ z++; } + /* copy digits to exponent */ while( sqlite3Isdigit(*z) ){ - eval = eval*10 + *z - '0'; + e = e*10 + (*z - '0'); z++; } - while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; } - while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; } - while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; } - while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; } - if( esign<0 ){ - v1 /= scale; - }else{ - v1 *= scale; + } + + /* adjust exponent by d, and update sign */ + e = (e*esign) + d; + if( e<0 ) { + esign = -1; + e *= -1; + } else { + esign = 1; + } + + /* if 0 significand */ + if( !s ) { + /* In the IEEE 754 standard, zero is signed. + ** Add the sign if we've seen at least one digit */ + result = (sign<0 && nDigits) ? -(double)0 : (double)0; + } else { + /* attempt to reduce exponent */ + if( esign>0 ){ + while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; + } + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + /* if exponent, scale significand as appropriate + ** and store in result. */ + if( e ){ + double scale = 1.0; + while( e>=16 ){ scale *= 1.0e+16; e -= 16; } + while( e>=4 ){ scale *= 1.0e+4; e -= 4; } + while( e>=1 ){ scale *= 1.0e+1; e -= 1; } + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } + } else { + result = (double)s; } } - *pResult = (double)(sign<0 ? -v1 : v1); + + /* store the result */ + *pResult = result; + + /* return number of characters used */ return (int)(z - zBegin); #else return sqlite3Atoi64(z, pResult); @@ -904,7 +944,7 @@ void sqlite3Put4byte(unsigned char *p, u32 v){ #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Translate a single byte of Hex into an integer. -** This routinen only works if h really is a valid hexadecimal +** This routine only works if h really is a valid hexadecimal ** character: 0..9a..fA..F */ static u8 hexToInt(int h){ diff --git a/test/nan.test b/test/nan.test index 4d61e939f7..25672cb24f 100644 --- a/test/nan.test +++ b/test/nan.test @@ -313,7 +313,7 @@ do_test nan-4.20 { set big [string repeat 9 10000].0e-9000 db eval "INSERT INTO t1 VALUES($big)" db eval {SELECT x, typeof(x) FROM t1} -} {{} null} +} {inf real}