bugfixes for addition/subtraction

This commit is contained in:
Jeff Wang 2019-03-27 05:19:09 -04:00
parent a742bb2059
commit 0ba2ca7710
3 changed files with 30 additions and 27 deletions

View File

@ -93,7 +93,7 @@ static void shift_left(dec80* x){
static void remove_leading_zeros(dec80* x){ static void remove_leading_zeros(dec80* x){
uint8_t digit100; uint8_t digit100;
uint8_t is_negative = (x->exponent < 0 ? 1 : 0); uint8_t is_negative = (x->exponent < 0 ? 1 : 0);
uint8_t exponent = get_exponent(x); int16_t exponent = get_exponent(x);
//find first non-zero digit100 //find first non-zero digit100
for (digit100 = 0; digit100 < DEC80_NUM_LSU; digit100++){ for (digit100 = 0; digit100 < DEC80_NUM_LSU; digit100++){
@ -103,6 +103,7 @@ static void remove_leading_zeros(dec80* x){
} }
exponent -= digit100 * 2; //base 100 exponent -= digit100 * 2; //base 100
//copy digit100s left if needed
if (digit100 != 0 && digit100 < DEC80_NUM_LSU){ //found non-zero digit100 if (digit100 != 0 && digit100 < DEC80_NUM_LSU){ //found non-zero digit100
uint8_t i; uint8_t i;
//copy digit100s //copy digit100s
@ -111,18 +112,15 @@ static void remove_leading_zeros(dec80* x){
} }
//zero out remaining digit100s, now that number left-aligned //zero out remaining digit100s, now that number left-aligned
zero_remaining_dec80(x, i); zero_remaining_dec80(x, i);
}
//ensure MSdigit in MSdigit100 is > 0 //ensure MSdigit in MSdigit100 is > 0
if (x->lsu[digit100] < 10) { if (x->lsu[0] < 10) {
shift_left(x); shift_left(x);
exponent--; exponent--;
} }
//write back exponent //write back exponent
if (is_negative){ set_exponent(x, exponent, is_negative);
x->exponent = exponent | 0x8000;
} else {
x->exponent = exponent & 0x7fff;
}
}
} }
void build_dec80(dec80* dest, const char* signif_str, int16_t exponent){ void build_dec80(dec80* dest, const char* signif_str, int16_t exponent){
@ -448,7 +446,9 @@ static void sub_mag(dec80* acc, const dec80* x){
//normalize //normalize
remove_leading_zeros(acc); remove_leading_zeros(acc);
remove_leading_zeros(&tmp); remove_leading_zeros(&tmp);
if (get_exponent(acc) != get_exponent(&tmp)){
_incr_exp(&tmp, get_exponent(acc)); _incr_exp(&tmp, get_exponent(acc));
}
#ifdef DEBUG_ADD #ifdef DEBUG_ADD
extern char buf[DECN_BUF_SIZE]; extern char buf[DECN_BUF_SIZE];
dec80_to_str(buf, &tmp); dec80_to_str(buf, &tmp);
@ -484,7 +484,7 @@ void add_decn(dec80* acc, const dec80* x){
return; return;
} }
//handle cases where signs differ //handle cases where signs differ
if (acc->exponent < 0 && x->exponent > 0){ if (acc->exponent < 0 && x->exponent >= 0){
// -acc, +x // -acc, +x
rel = compare_magn(acc, x); rel = compare_magn(acc, x);
if (rel == 1){ if (rel == 1){
@ -508,7 +508,7 @@ void add_decn(dec80* acc, const dec80* x){
set_dec80_zero(acc); set_dec80_zero(acc);
return; return;
} }
} else if (acc->exponent > 0 && x->exponent < 0){ } else if (acc->exponent >= 0 && x->exponent < 0){
// +acc, -x // +acc, -x
rel = compare_magn(acc, x); rel = compare_magn(acc, x);
if (rel == 1){ if (rel == 1){
@ -523,7 +523,6 @@ void add_decn(dec80* acc, const dec80* x){
#endif #endif
copy_decn(&tmp, x); copy_decn(&tmp, x);
sub_mag(&tmp, acc); sub_mag(&tmp, acc);
negate_decn(&tmp);
copy_decn(acc, &tmp); copy_decn(acc, &tmp);
return; return;
} else { //equal } else { //equal
@ -546,11 +545,14 @@ void add_decn(dec80* acc, const dec80* x){
dec80_to_str(buf, &tmp); dec80_to_str(buf, &tmp);
printf(" rem_leading_zeros tmp: %s\n", buf); printf(" rem_leading_zeros tmp: %s\n", buf);
#endif #endif
rel = compare_magn(acc, &tmp); if (get_exponent(acc) > get_exponent(&tmp)){
if (rel == 1){
_incr_exp(&tmp, get_exponent(acc)); _incr_exp(&tmp, get_exponent(acc));
} else if (rel == -1){ } else if (get_exponent(acc) < get_exponent(&tmp)){
_incr_exp(acc, get_exponent(&tmp)); //shift significand and adjust exponent to match
for (i = 0; i < get_exponent(&tmp) - get_exponent(acc); i++){
shift_right(acc);
}
set_exponent(acc, get_exponent(&tmp), (acc->exponent < 0));
} }
#ifdef DEBUG_ADD #ifdef DEBUG_ADD
extern char buf[DECN_BUF_SIZE]; extern char buf[DECN_BUF_SIZE];

View File

@ -20,7 +20,7 @@
typedef struct { typedef struct {
int16_t exponent; //MSBit is sign of dec80 number, bottom 15 bits are 2's Compl exponent int16_t exponent; //MSBit is sign of dec80 number, bottom 15 bits are 2's Compl exponent
uint8_t lsu[DEC80_NUM_LSU]; //lsu[0] holds most-significant 2 digits (base 100) uint8_t lsu[DEC80_NUM_LSU]; //lsu[0] holds most-significant 2 digits (base 100)
//implicit decimal point between (lsu[0]/100) and (lsu[0]%100) //implicit decimal point between (lsu[0]/10) and (lsu[0]%10)
} dec80; } dec80;
//remove sign bit, and return 15 bit exponent sign-extended to 16 bits //remove sign bit, and return 15 bit exponent sign-extended to 16 bits

View File

@ -43,6 +43,7 @@ int main(void){
dec80_to_str(buf, &diff); dec80_to_str(buf, &diff);
printf("\n : %s\n\n", buf); printf("\n : %s\n\n", buf);
//new acc for acc - b test
dec80_to_str(buf, &acc); dec80_to_str(buf, &acc);
printf("acc: %s\n", buf); printf("acc: %s\n", buf);
negate_decn(&b); negate_decn(&b);
@ -51,7 +52,7 @@ int main(void){
add_decn(&acc, &b); add_decn(&acc, &b);
dec80_to_str(buf, &acc); dec80_to_str(buf, &acc);
//compare result //compare result of new acc - b
printf("\nacc - b: %s", buf); printf("\nacc - b: %s", buf);
printf("\n : %s", "-9.234567890123456E3"); printf("\n : %s", "-9.234567890123456E3");
build_dec80(&diff, "-9.234567890123456", 3); build_dec80(&diff, "-9.234567890123456", 3);