-C Because\sversion\s3.52.0\swas\swithdrawn,\sthat\smeans\sQRF\shas\snever\sbeen\nofficially\sreleased.\s\sHence\sthe\snew\snMultiInsert\sfield\sof\sthe\sspec\ncan\sbe\smoved\sout\sof\sthe\sextensions\sarea\sand\sinto\sthe\smain\spart\sof\sthe\nspec,\sand\sthe\sversion\snumber\scan\sdrop\sback\sfrom\s2\sto\s1.
-D 2026-03-21T19:49:38.046
+C Performance\simprovements\sin\sthe\sfloating-point\snumber\sparser.
+D 2026-03-22T02:26:38.451
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
-F src/util.c 51662502243422f3238a7220fe00de32d9a7d0d3149dd33c6d721d7039cb2e74
+F src/util.c 024100479ff7cf06a5635d4353e0ba1f1b9b6d24930b5d88fbe33afc4d85b825
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
F src/vdbe.c dbafc6f5762f9ae90d9dc9ed065a31743a8ceafbdbfb1a0a3a228921fb3cc36a
F src/vdbe.h 70e862ac8a11b590f8c1eaac17a0078429d42bc4ea3f757a9af0f451dd966a71
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 8e1d0c4eac303cd0834449f4792605c0ed983db1f360af42300f0048dadbbef8
-R a41bf058e42684a09ca798bb17f3d8b8
+P cf19982241afb17e3db4148b8257f6737141935a291c340ab085c42ed946af1a
+R fb2b20242625ffa81d29970e27082419
+T *branch * optimize-atof
+T *sym-optimize-atof *
+T -sym-trunk *
U drh
-Z 3d0e6419f275717c17fd604ea7b5f9df
+Z e1f1ebc5f1aeac5a9d37ac5faaa6d91b
# Remove this line to create a well-formed Fossil manifest.
#endif
int sqlite3AtoF(const char *z, double *pResult){
#ifndef SQLITE_OMIT_FLOATING_POINT
- /* sign * significand * (10 ^ (esign * exponent)) */
- int neg = 0; /* True for a negative value */
- u64 s = 0; /* mantissa */
- int d = 0; /* Value is s * pow(10,d) */
- int nDigit = 0; /* Number of digits processed */
- int eType = 1; /* 1: pure integer, 2+: fractional */
-
- *pResult = 0.0; /* Default return value, in case of an error */
-
- /* skip leading spaces */
- while( sqlite3Isspace(*z) ) z++;
-
- /* get sign of significand */
- if( *z=='-' ){
+ int neg = 0; /* True for a negative value */
+ u64 s = 0; /* mantissa */
+ int d = 0; /* Value is s * pow(10,d) */
+ int seenDigit = 0; /* true if any digits seen */
+ int seenFP = 0; /* True if we've seen a "." or a "e" */
+
+ start_of_text:
+ if( sqlite3Isdigit(z[0]) ){
+ parse_integer_part:
+ seenDigit = 1;
+ s = z[0] - '0';
+ z++;
+ while( sqlite3Isdigit(z[0]) ){
+ s = s*10 + (z[0] - '0');
+ z++;
+ if( s>=(LARGEST_INT64-9)/10 ){
+ while( sqlite3Isdigit(z[0]) ){ z++; d++; }
+ break;
+ }
+ }
+ }else if( z[0]=='-' ){
neg = 1;
z++;
- }else if( *z=='+' ){
+ if( sqlite3Isdigit(z[0]) ) goto parse_integer_part;
+ }else if( z[0]=='+' ){
z++;
- }
-
- /* copy max significant digits to significand */
- while( sqlite3Isdigit(*z) ){
- s = s*10 + (*z - '0');
- z++; nDigit++;
- if( s>=((LARGEST_INT64-9)/10) ){
- /* skip non-significant significand digits
- ** (increase exponent by d to shift decimal left) */
- while( sqlite3Isdigit(*z) ){ z++; d++; }
- }
+ if( sqlite3Isdigit(z[0]) ) goto parse_integer_part;
+ }else if( sqlite3Isspace(z[0]) ){
+ do{ z++; }while( sqlite3Isspace(z[0]) );
+ goto start_of_text;
+ }else{
+ s = 0;
}
/* if decimal point is present */
if( *z=='.' ){
z++;
- eType++;
- /* copy digits from after decimal to significand
- ** (decrease exponent by d to shift decimal right) */
- while( sqlite3Isdigit(*z) ){
+ seenFP = 1;
+ if( sqlite3Isdigit(z[0]) ){
+ seenDigit = 1;
if( s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- d--;
- nDigit++;
+ s = s*10 + z[0] - '0';
+ d = -1;
}
z++;
+ while( sqlite3Isdigit(z[0]) ){
+ if( s<((LARGEST_INT64-9)/10) ){
+ s = s*10 + (*z - '0');
+ d--;
+ }
+ z++;
+ }
}
}
+ if( !seenDigit ){
+ *pResult = 0.0;
+ return 0;
+ }
+
/* if exponent is present */
if( *z=='e' || *z=='E' ){
- int esign = 1; /* sign of exponent */
+ int esign;
z++;
- eType++;
-
+
/* get sign of exponent */
if( *z=='-' ){
esign = -1;
z++;
- }else if( *z=='+' ){
- z++;
+ }else{
+ esign = +1;
+ if( *z=='+' ){
+ z++;
+ }
}
/* copy digits to exponent */
if( sqlite3Isdigit(*z) ){
int exp = *z - '0';
z++;
+ seenFP = 1;
while( sqlite3Isdigit(*z) ){
exp = exp<10000 ? (exp*10 + (*z - '0')) : 10000;
z++;
}
d += esign*exp;
}else{
- eType = -1;
+ z--; /* Leave z[0] at 'e' or '+' or '-',
+ ** so that the return is 0 or -1 */
}
}
/* skip trailing spaces */
while( sqlite3Isspace(*z) ) z++;
- /* Zero is a special case */
- if( s==0 ){
- *pResult = neg ? -0.0 : +0.0;
- }else{
- *pResult = sqlite3Fp10Convert2(s,d);
- if( neg ) *pResult = -*pResult;
- assert( !sqlite3IsNaN(*pResult) );
- }
+ /* Convert s*pow(10,d) into real */
+ *pResult = s ? sqlite3Fp10Convert2(s,d) : 0.0;
+ if( neg ) *pResult = -*pResult;
+ assert( !sqlite3IsNaN(*pResult) );
/* return true if number and no extra non-whitespace characters after */
- if( z[0]==0 && nDigit>0 ){
- return eType;
- }else if( eType>=2 && nDigit>0 ){
- return -1;
+ if( z[0]==0 ){
+ return seenFP+1;
+ }else if( seenFP ){
+ return -1; /* Prefix is a floating point number */
}else{
- return 0;
+ return 0; /* Prefix is just an integer */
}
#else
return !sqlite3Atoi64(z, pResult, strlen(z), SQLITE_UTF8);