fix exponent display

This commit is contained in:
Jeff Wang 2019-04-01 01:12:02 -04:00
parent 8114853d14
commit 8aec2ae134
5 changed files with 142 additions and 85 deletions

View File

@ -120,9 +120,8 @@ The keys on the original calculator map as follows:
- `mode`: reserved for a future shift key
# Bugs
1. Currently, when displaying numbers, the exponent may be cut off if the number is too long.
1. Initially, the exponent for the 1st number entered after poweron is random.
1. Currently, trying to display numbers between `[0.1, 1)` causes the calculator to crash.
1. There are other calculations which can randomly cause the calculator to crash.
1. There are probably more bugs waiting to be discovered.
# Internals

View File

@ -768,7 +768,7 @@ void div_decn(dec80* acc, const dec80* x){
}
//buf should hold at least 18 + 4 + 5 + 1 = 28
void dec80_to_str(char* buf, const dec80* x){
int8_t decn_to_str(char* buf, const dec80* x){
#define INSERT_DOT() buf[i++]='.'
uint8_t i = 0;
uint8_t digit100;
@ -787,7 +787,7 @@ void dec80_to_str(char* buf, const dec80* x){
#endif
buf[0] = '0';
buf[1] = '\0';
return;
return 0;
}
//check sign of number
if (tmp.exponent < 0){
@ -821,10 +821,8 @@ void dec80_to_str(char* buf, const dec80* x){
} else {
if (exponent == 0){
INSERT_DOT();
exponent--;
} else if (exponent > 0){
exponent--;
}
exponent--;
}
//print 2nd digit
buf[i] = (tmp.lsu[0] % 10) + '0';
@ -836,10 +834,8 @@ void dec80_to_str(char* buf, const dec80* x){
if (!use_sci){
if (exponent == 0){
INSERT_DOT();
exponent--;
} else if (exponent > 0){
exponent--;
}
exponent--;
}
//print rest of significand
for (digit100 = 1 ; digit100 < DEC80_NUM_LSU; digit100++){
@ -849,10 +845,8 @@ void dec80_to_str(char* buf, const dec80* x){
if (!use_sci){
if (exponent == 0){
INSERT_DOT();
exponent--;
} else if (exponent > 0){
exponent--;
}
exponent--;
}
//print 2nd digit
buf[i] = (tmp.lsu[digit100] % 10) + '0';
@ -860,17 +854,17 @@ void dec80_to_str(char* buf, const dec80* x){
if (!use_sci){
if (exponent == 0){
INSERT_DOT();
exponent--;
} else if (exponent > 0){
exponent--;
}
exponent--;
}
//track trailing 0s
if (tmp.lsu[digit100] == 0 && (use_sci || exponent < -1)){
trailing_zeros += 2;
} else if (tmp.lsu[digit100] == 0 && (use_sci || exponent < 0)){
trailing_zeros += 1;
} else if (tmp.lsu[digit100] == 10 && (use_sci || exponent < 0)){
if (tmp.lsu[digit100] == 0 && (use_sci || exponent < 0)){
if (use_sci || exponent < -2){ //xx.00
trailing_zeros += 2;
} else if (exponent == -2){ //xx.0
trailing_zeros += 1;
}
} else if (tmp.lsu[digit100]%10 == 0 && (use_sci || exponent < 0)){
trailing_zeros = 1;
} else {
trailing_zeros = 0;
@ -881,6 +875,7 @@ void dec80_to_str(char* buf, const dec80* x){
if (use_sci || exponent <= 0){
i -= trailing_zeros;
}
buf[i] = '\0';
//calculate exponent
exponent = get_exponent(&tmp); //base 100
@ -888,19 +883,10 @@ void dec80_to_str(char* buf, const dec80* x){
printf (" exponent (%d)", exponent);
#endif
//print exponent
if (use_sci && exponent != 0){
buf[i] = 'E';
i++;
if (exponent < 0){
buf[i] = '-';
i++;
u32str(-exponent, &buf[i], 10); //adds null terminator automatically
} else {
u32str(exponent, &buf[i], 10); //adds null terminator automatically
}
if (use_sci){
return exponent;
} else {
//null terminate
buf[i] = '\0';
return 0;
}
#ifdef DEBUG
@ -912,5 +898,25 @@ void dec80_to_str(char* buf, const dec80* x){
#endif
}
#ifdef DESKTOP
//complete string including exponent
void decn_to_str_complete(char* buf, const dec80* x){
int8_t exponent = decn_to_str(buf, x);
int i;
//find end of string
for (i = 0; buf[i] != '\0'; i++);
//add exponent
if (exponent != 0){
buf[i++] = 'E';
if (exponent < 0){
buf[i++] = '-';
u32str(-exponent, &buf[i], 10); //adds null terminator automatically
} else {
u32str(exponent, &buf[i], 10); //adds null terminator automatically
}
}
}
#endif

View File

@ -8,6 +8,7 @@
#define SRC_DEC_DECN_H_
#include <stdint.h>
#include "../utils.h"
#define DEC80_NUM_LSU 9
@ -49,6 +50,11 @@ void div_decn(dec80* acc, const dec80* x);
//buf should hold at least 18 + 4 + 5 + 1 = 28
#define DECN_BUF_SIZE 28
void dec80_to_str(char* buf, const dec80* x);
int8_t decn_to_str(char* buf, const dec80* x);
#ifdef DESKTOP
//complete string including exponent
void decn_to_str_complete(char* buf, const dec80* x);
#endif
#endif /* SRC_DEC_DECN_H_ */

View File

@ -13,169 +13,169 @@ int main(void){
dec80 acc, b;
build_dec80(&acc, "0.0009234567890123456", 7);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
build_dec80(&acc, "9.234567890123456", 3);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
negate_decn(&acc);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("-acc: %s\n", Buf);
build_dec80(&b, "-92.3456789012345678", 1);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("-acc: %s\n", Buf);
//compare result of b - acc
add_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("b - a: %s\n", Buf);
printf(" : %s\n", "-10158.0246791358016");
dec80 diff;
build_dec80(&diff, "-1.01580246791358016", 4);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc for acc - b test
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc: %s\n", Buf);
negate_decn(&b);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" -b: %s\n", Buf);
add_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
//compare result of new acc - b
printf("acc - b: %s\n", Buf);
printf(" : %s\n", "-9234.567890123456");
build_dec80(&diff, "-9.234567890123456", 3);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for multiply test
// build_dec80(&acc, "7", 2);
build_dec80(&acc, "92.34567890123456", 2);
build_dec80(&b, "-92.3456789012345678", 1);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
mult_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc*b: %s\n", Buf);
printf(" : %s\n", "-8527724.41172991849");
build_dec80(&diff, "-8.52772441172991849", 6);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "3.14", 88);
build_dec80(&b, "-1.5", -2);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "-2.09333333333333334E90");
build_dec80(&diff, "-2.09333333333333334", 90);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "4", 0);
build_dec80(&b, "4", 0);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "1.00000000");
printf(" : %s\n", "1.");
build_dec80(&diff, "1", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "1", 0);
build_dec80(&b, "3", 0);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "0.333333333333333336");
build_dec80(&diff, "3.33333333333333336", -1);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n", Buf);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//small fractions >= 1/10
build_dec80(&acc, "0.333", 0);
build_dec80(&b, "3.33", -1);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" a : %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b : %s\n", Buf);
negate_decn(&b);
add_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("a - b: %s\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "500", 0);
build_dec80(&b, "99", 0);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "5.05050505050505055");
build_dec80(&diff, "5.05050505050505055", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "500", 0);
build_dec80(&b, "2", 0);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
dec80_to_str(Buf, &b);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
dec80_to_str(Buf, &acc);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "250.0");
printf(" : %s\n", "250.");
build_dec80(&diff, "250", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
dec80_to_str(Buf, &diff);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);

View File

@ -105,7 +105,7 @@ static void latch_on(void)
char Buf[DECN_BUF_SIZE];
__xdata char EntryBuf[MAX_CHARS_PER_LINE + 1];
__xdata uint8_t ExpBuf[2] = {0, 0};
__xdata uint8_t ExpBuf[2];
//#define DEBUG_UPTIME
/*********************************************/
@ -123,6 +123,7 @@ int main()
uint8_t entering_exp = ENTERING_DONE;
uint8_t no_lift = 0;
uint8_t exp_i = 0;
int8_t disp_exponent;
#ifdef DEBUG_KEYS
uint8_t j = 0;
const uint8_t* keys;
@ -139,6 +140,9 @@ int main()
KeyInit();
BACKLIGHT_ON(); //turn on led backlight
ExpBuf[0] = 0;
ExpBuf[1] = 0;
#ifdef DEBUG_UPTIME
i = 0;
#endif
@ -157,12 +161,24 @@ int main()
#else
//display y register on first line
if (entering_exp == ENTERING_DONE){
dec80_to_str(Buf, get_y());
disp_exponent = decn_to_str(Buf, get_y());
} else {
//display x on 1st line, entered number on 2nd line
dec80_to_str(Buf, get_x());
disp_exponent = decn_to_str(Buf, get_x());
}
if (disp_exponent == 0){
LCD_OutString(Buf, MAX_CHARS_PER_LINE);
} else { //have exponent to display
LCD_OutString(Buf, MAX_CHARS_PER_LINE - 3);
if (disp_exponent < 0){
TERMIO_PutChar('-');
disp_exponent = -disp_exponent;
} else {
TERMIO_PutChar(' ');
}
TERMIO_PutChar((disp_exponent / 10) + '0');
TERMIO_PutChar((disp_exponent % 10) + '0');
}
LCD_OutString(Buf, MAX_CHARS_PER_LINE);
#endif //DEBUG_UPTIME
#ifdef DEBUG_KEYS
@ -208,8 +224,17 @@ int main()
//////////
case '0': {
if (entering_exp >= ENTERING_EXP){
ExpBuf[exp_i] = 0;
exp_i = (exp_i + 1) & 1;
if (exp_i == 0){
ExpBuf[0] = 0;
exp_i = 1;
} else {
ExpBuf[1] = ExpBuf[0];
ExpBuf[0] = 0;
exp_i++;
if (exp_i > 2){
exp_i = 1;
}
}
} else if (entering_exp == ENTERING_DONE){
entering_exp = ENTERING_SIGNIF;
EntryBuf[entry_i] = KEY_MAP[i_key];
@ -230,8 +255,17 @@ int main()
case '8': //fallthrough
case '9': {
if (entering_exp >= ENTERING_EXP){
ExpBuf[exp_i] = KEY_MAP[i_key] - '0';
exp_i = (exp_i + 1) & 1;
if (exp_i == 0){
ExpBuf[0] = KEY_MAP[i_key] - '0';
exp_i = 1;
} else {
ExpBuf[1] = ExpBuf[0];
ExpBuf[0] = KEY_MAP[i_key] - '0';
exp_i++;
if (exp_i > 2){
exp_i = 1;
}
}
} else if (entering_exp == ENTERING_DONE){
entering_exp = ENTERING_SIGNIF;
EntryBuf[entry_i] = KEY_MAP[i_key];
@ -349,8 +383,20 @@ int main()
//print X
LCD_ClearToEnd(0); //go to 2nd row
if (entering_exp == ENTERING_DONE){
dec80_to_str(Buf, get_x());
LCD_OutString(Buf, MAX_CHARS_PER_LINE);
disp_exponent = decn_to_str(Buf, get_x());
if (disp_exponent == 0){
LCD_OutString(Buf, MAX_CHARS_PER_LINE);
} else { //have exponent to display
LCD_OutString(Buf, MAX_CHARS_PER_LINE - 3);
if (disp_exponent < 0){
TERMIO_PutChar('-');
disp_exponent = -disp_exponent;
} else {
TERMIO_PutChar(' ');
}
TERMIO_PutChar((disp_exponent / 10) + '0');
TERMIO_PutChar((disp_exponent % 10) + '0');
}
} else if (entry_i == 0){
TERMIO_PutChar('0');
} else if (entering_exp < ENTERING_EXP){