1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-05 21:40:25 +00:00

Optimise func_val, especially for common usecases with small integers.

This commit is contained in:
Luke Ceddia 2015-08-16 23:07:39 +10:00
parent c65b2f14f0
commit d4c0a4c5a1

View file

@ -13923,7 +13923,8 @@ void qbs_input(int32 numvariables,uint8 newline){
}//qbs_input }//qbs_input
long double func_val(qbs *s){ long double func_val(qbs *s){
static int32 i,i2,step,c,num_significant_digits,most_significant_digit_position; char c;
static int32 i,i2,step,num_significant_digits,most_significant_digit_position;
static int32 num_exponent_digits; static int32 num_exponent_digits;
static int32 negate,negate_exponent; static int32 negate,negate_exponent;
static uint8 significant_digits[256]; static uint8 significant_digits[256];
@ -13945,97 +13946,127 @@ long double func_val(qbs *s){
i=0; i=0;
for (i=0;i<s->len;i++){ for (i=0;i<s->len;i++){
c=s->chr[i]; c=(char)s->chr[i];
switch (c) {
case ' ':
case '\t':
goto whitespace;
break;
if ((c==32)||(c==9)) goto whitespace; case '&':
if (c==38){//&
if (step==0) goto hex; if (step==0) goto hex;
goto finish; goto finish;
} break;
if (c==45){//- case '-':
if (step==0){negate=1; step=1; goto checked;} if (step==0) {
if (step==3){negate_exponent=1; step=4; goto checked;} negate = 1;
step = 1;
goto checked;
}
else if (step==3) {
negate_exponent = 1;
step = 4;
goto checked;
}
goto finish; goto finish;
} break;
if (c==43){//+ case '+':
if (step==0){step=1; goto checked;} if (step==0 || step==3) {
if (step==3){step=4; goto checked;} step++;
goto checked;
}
goto finish; goto finish;
} break;
if ((c>=48)&&(c<=57)){//0-9
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (step<=1){//before decimal point if (step<=1){//before decimal point
step=1; step=1;
if ((num_significant_digits)||(c>48)){ if ((num_significant_digits)||(c>48)){
most_significant_digit_position++; most_significant_digit_position++;
significant_digits[num_significant_digits]=c; significant_digits[num_significant_digits]=c;
num_significant_digits++; num_significant_digits++;
value=value*10+c-48; value=value*10+c-48;
} }
}
else if (step==2){//after decimal point
if ((num_significant_digits==0)&&(c==48)) most_significant_digit_position--;
if ((num_significant_digits)||(c>48)){
significant_digits[num_significant_digits]=c;
num_significant_digits++;
}
} }
if (step==2){//after decimal point else if (step>=3){//exponent
if ((num_significant_digits==0)&&(c==48)) most_significant_digit_position--; step=4;
if ((num_significant_digits)||(c>48)){ if ((num_exponent_digits)||(c>48)){
significant_digits[num_significant_digits]=c; if (num_exponent_digits>=18) goto finish;
num_significant_digits++; exponent_value*=10; exponent_value=exponent_value+c-48;//precalculate
} num_exponent_digits++;
}
} }
if (step>=3){//exponent
step=4;
if ((num_exponent_digits)||(c>48)){
if (num_exponent_digits>=18) goto finish;
exponent_value*=10; exponent_value=exponent_value+c-48;//precalculate
num_exponent_digits++;
}
}
goto checked; goto checked;
} break;
if (c==46){//. case '.':
if (step>1) goto finish; if (step>1) goto finish;
step=2; goto checked; step=2; goto checked;
} break;
if ((c==68)||(c==69)||(c==100)||(c==101)){//D,E,d,e case 'D':
case 'E':
case 'd':
case 'e':
if (step>2) goto finish; if (step>2) goto finish;
step=3; goto checked; step=3; goto checked;
} break;
default:
goto finish;//invalid character goto finish;//invalid character
break;
}
checked: checked:
whitespace:; whitespace:;
} }
finish:; finish:;
//Check for all-zero mantissa
if (num_significant_digits==0) return 0; if (num_significant_digits==0) return 0;
//adjust exponent value appropriately
//if most_significant_digit_position=1, then no change need occur
exponent_value=exponent_value+most_significant_digit_position-1;
if (exponent_value==0){ //If no exponent (or E0) and no decimal part and no chance of overflowing value, return straight away
if (num_significant_digits==most_significant_digit_position){ if (exponent_value==0 && num_significant_digits==most_significant_digit_position && num_significant_digits < 19){
if (negate) value=-value; return negate ? -value : value;
return value;
}
} }
//normalise number (change 123.456E2 to 1.23456E4, or 123.456 to 1.23456E2)
exponent_value=exponent_value+most_significant_digit_position-1;
if (negate_exponent) exponent_value=-exponent_value; if (negate_exponent) exponent_value=-exponent_value;
i=0; i=0;
//we are now building a floating point number in ascii characters
if (negate) {built_number[i]=45; i++;}//- if (negate) {built_number[i]=45; i++;}//-
if (num_significant_digits){ if (num_significant_digits){
//build nomalised mantissa
for (i2=0;i2<num_significant_digits;i2++){ for (i2=0;i2<num_significant_digits;i2++){
if (i2==1){built_number[i]=46; i++;} if (i2==1){
built_number[i]=46;
i++;
}
built_number[i]=significant_digits[i2]; i++; built_number[i]=significant_digits[i2]; i++;
} }
built_number[i]=69; i++;//E built_number[i]=69; i++;//E
//add exponent's value //add exponent
#ifdef QB64_WINDOWS #ifdef QB64_WINDOWS
i2=sprintf((char*)&built_number[i],"%I64i",exponent_value); i2=sprintf((char*)&built_number[i],"%I64i",exponent_value);
#else #else