add power function, try to reduce stack usage, standardize unary ops

This commit is contained in:
Jeff Wang 2019-10-06 16:58:07 -04:00
parent bf0bfe39a4
commit 75dd499630
5 changed files with 94 additions and 29 deletions

View File

@ -61,6 +61,14 @@ static void do_binary_op(void (*f_ptr)(void)){
pop();
}
static void do_unary_op(void (*f_ptr)(void)){
if (!decn_is_nan(&stack(STACK_X))){
copy_decn(&AccDecn, &stack(STACK_X));
f_ptr();
copy_decn(&stack(STACK_X), &AccDecn);
}
}
static void toggle_shifted(void){
IsShifted ^= 1;
}
@ -118,24 +126,47 @@ void process_cmd(char cmd){
toggle_shifted();
} break;
//////////
case '5':{
if (IsShifted){ //e^x
do_unary_op(exp_decn);
IsShifted = 0;
}
} break;
//////////
case '6':{
if (IsShifted){ //10^x
do_unary_op(exp10_decn);
IsShifted = 0;
}
} break;
//////////
case '9':{
if (IsShifted && !decn_is_nan(&stack(STACK_X))){ //log10(x)
copy_decn(&AccDecn, &stack(STACK_X));
log10_decn();
copy_decn(&stack(STACK_X), &AccDecn);
if (IsShifted){ //log10(x)
do_unary_op(log10_decn);
IsShifted = 0;
}
} break;
//////////
case '8':{
if (IsShifted && !decn_is_nan(&stack(STACK_X))){ //ln(x)
copy_decn(&AccDecn, &stack(STACK_X));
ln_decn();
copy_decn(&stack(STACK_X), &AccDecn);
if (IsShifted){ //ln(x)
do_unary_op(ln_decn);
IsShifted = 0;
}
} break;
//////////
case '7':{
if (decn_is_nan(&stack(STACK_Y)) || decn_is_nan(&stack(STACK_X))){
set_dec80_NaN(&stack(STACK_Y));
} else {
copy_decn(&AccDecn, &stack(STACK_Y));
copy_decn(&BDecn, &stack(STACK_X));
pow_decn();
copy_decn(&stack(STACK_Y), &AccDecn);
}
pop();
IsShifted = 0;
} break;
//////////
} //switch(cmd)
}

View File

@ -30,6 +30,9 @@
#undef DEBUG_MULT
#undef DEBUG_DIV
#undef DEBUG_LOG
#undef DEBUG_LOG_ALL
#undef DEBUG_EXP
#undef DEBUG_EXP_ALL
#endif
#ifdef DESKTOP
@ -52,7 +55,7 @@ __idata dec80 AccDecn, BDecn;
__idata dec80 TmpDecn; //used by add_decn() and mult_decn()
__idata dec80 Tmp2Decn; //used by recip_decn() and ln_decn()
__idata dec80 Tmp3Decn; //used by recip_decn() and ln_decn()
__idata dec80 Tmp4Decn; //used by div_decn() and ln_decn()
__idata dec80 Tmp4Decn; //used by div_decn() and pow_decn()
__xdata char Buf[DECN_BUF_SIZE];
@ -1025,17 +1028,17 @@ void ln_decn(void){
#undef NUM_TIMES
}
//inline void log10_decn(void){
// ln_decn();
// copy_decn(&BDecn, &DECN_LN_10);
// div_decn();
//}
inline void log10_decn(void){
ln_decn();
copy_decn(&BDecn, &DECN_LN_10);
div_decn();
}
void exp_decn(void){
uint8_t j, k;
uint8_t need_recip;
uint8_t need_recip = 0;
#define SAVED Tmp2Decn
#define NUM_TIMES Tmp3Decn
@ -1173,16 +1176,42 @@ void exp_decn(void){
}
} while (1);
#ifdef DEBUG_EXP
decn_to_str_complete(&AccDecn);
printf("exp() before recip: %s\n", Buf);
#endif
//take reciprocal if exp was negative
if (need_recip){
recip_decn();
}
#ifdef DEBUG_EXP
decn_to_str_complete(&AccDecn);
printf("exp() final val: %s\n", Buf);
#endif
//try not to pollute namespace
#undef SAVED
#undef NUM_TIMES
}
inline void exp10_decn(void){
//exp10_decn() = exp_decn(AccDecn * ln(10))
copy_decn(&BDecn, &DECN_LN_10);
mult_decn();
exp_decn();
}
//inline void pow_decn(void)
//{
// copy_decn(&Tmp4Decn, &BDecn); //save b
// ln_decn();
// copy_decn(&BDecn, &Tmp4Decn); //restore b
// mult_decn(); //accum = b*ln(accum)
// exp_decn();
//}
static void set_str_error(void){
Buf[0] = 'E';
Buf[1] = 'r';

View File

@ -55,7 +55,7 @@ static const dec80 DECN_LN_10 = {
exp_t get_exponent(const dec80* x);
void copy_decn(dec80* dest, const dec80* src);
extern __idata dec80 AccDecn, BDecn;
extern __idata dec80 AccDecn, BDecn, Tmp4Decn;
void build_dec80(__xdata const char* signif_str, exp_t exponent);
@ -70,20 +70,19 @@ void recip_decn(void);
void div_decn(void);
void ln_decn(void);
//inline void log10_decn(void);
#define log10_decn() do { \
ln_decn(); \
copy_decn(&BDecn, &DECN_LN_10); \
div_decn(); \
} while(0);
void log10_decn(void);
void exp_decn(void);
//exp10_decn() = exp_decn(AccDecn * ln(10))
#define exp10_decn() do { \
copy_decn(&BDecn, &DECN_LN_10); \
mult_decn(); \
exp_decn(); \
} while(0);
void exp10_decn(void);
//calculate AccDecn = AccDecn ^ BDecn
#define pow_decn() do {\
copy_decn(&Tmp4Decn, &BDecn); \
ln_decn(); \
copy_decn(&BDecn, &Tmp4Decn); \
mult_decn(); \
exp_decn(); \
} while (0);
//Buf should hold at least 18 + 4 + 5 + 1 = 28
#define DECN_BUF_SIZE 28

View File

@ -262,6 +262,12 @@ int main(void){
"-22.3227534185273434", 0
);
//new acc for log test
log_test(
"2.02", 0,
"0.703097511413113392", 0
);
//new acc for log test
log10_test(
"1.5", 0,

View File

@ -125,7 +125,7 @@ static void latch_on(void)
__xdata char EntryBuf[MAX_CHARS_PER_LINE + 1];
__xdata uint8_t ExpBuf[2];
__xdata const char VER_STR[32+1] = "STC RPN Calculator v1.04";
__xdata const char VER_STR[32+1] = "STC RPN Calculator v1.05";
enum {