More simplification of the sqlite3AtoF() routine. Add special comments

to indicate branches that are for optimization purposes only and that give
the correct answer even if always or never taken.

FossilOrigin-Name: 0065fe97cb8e5076acae1bf1560fd2f69dab9014
This commit is contained in:
drh 2016-04-27 15:24:13 +00:00
parent c6daa01c05
commit ad975d539e
3 changed files with 52 additions and 39 deletions

View File

@ -1,5 +1,5 @@
C Remove\sstill\smore\sunnecessary\sbranches\sfrom\ssqlite3AtoF().
D 2016-04-27T02:35:03.572
C More\ssimplification\sof\sthe\ssqlite3AtoF()\sroutine.\s\sAdd\sspecial\scomments\nto\sindicate\sbranches\sthat\sare\sfor\soptimization\spurposes\sonly\sand\sthat\sgive\nthe\scorrect\sanswer\seven\sif\salways\sor\snever\staken.
D 2016-04-27T15:24:13.573
F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 562f7a85d933b7173a29e331deb28d85d6208f7c
F src/util.c d0899604c30b4a9d493980aa7742eeda383fff6d
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P dd69e53cb077873171af5312c633ca185595bf31
R 4f22b05e3bc28723a991a2f87c87962e
P 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15
R 676347b15924e075b34cabb43dd7e840
U drh
Z 439e39a464407086f87a7be758f8e1c8
Z 680dc6a7c6e0d675cd4dc0c16abcab9d

View File

@ -1 +1 @@
3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15
0065fe97cb8e5076acae1bf1560fd2f69dab9014

View File

@ -355,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
int nDigits = 0;
int nonNum = 0;
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@ -368,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
for(i=3-enc; i<length && z[i]==0; i+=2){}
nonNum = i<length;
zEnd = z+i+enc-3;
zEnd = &z[i^1];
z += (enc&1);
}
@ -414,7 +414,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
if( z>=zEnd ) goto do_atof_calc;
/* This branch is needed to avoid a (harmless) buffer overread. The
** special comment alerts the mutation tester that the correct answer
** is obtained even if the branch is omitted */
if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
/* get sign of exponent */
if( *z=='-' ){
esign = -1;
@ -443,41 +448,51 @@ do_atof_calc:
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 */
if( s==0 ) {
/* In the IEEE 754 standard, zero is signed. */
result = sign<0 ? -(double)0 : (double)0;
} else {
/* attempt to reduce exponent */
if( esign>0 ){
while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
}else{
while( !(s%10) && e>0 ) e--,s/=10;
/* Attempt to reduce exponent.
**
** Branches that are not required for the correct answer but which only
** help to obtain the correct answer faster are marked with special
** comments, as a hint to the mutation tester.
*/
while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
if( esign>0 ){
if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
s *= 10;
}else{
if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
s /= 10;
}
e--;
}
/* adjust the sign of significand */
s = sign<0 ? -s : s;
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
result = (double)s;
}else{
LONGDOUBLE_TYPE scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 && e<342 ){
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
result = s * scale;
result *= 1.0e+308;
}
}else if( e>=342 ){
if( esign<0 ){
result = 0.0*s;
}else{
result = 1e308*1e308*s; /* Infinity */
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
result = s * scale;
result *= 1.0e+308;
}
}else{ assert( e>=342 );
if( esign<0 ){
result = 0.0*s;
}else{
result = 1e308*1e308*s; /* Infinity */
}
}
}else{
/* 1.0e+22 is the largest power of 10 than can be
@ -490,8 +505,6 @@ do_atof_calc:
result = s * scale;
}
}
} else {
result = (double)s;
}
}
@ -499,7 +512,7 @@ do_atof_calc:
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
return z==zEnd && nDigits>0 && eValid && nonNum==0;
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */