bugfixes for addition/subtraction
This commit is contained in:
parent
a742bb2059
commit
0ba2ca7710
@ -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
|
|
||||||
if (x->lsu[digit100] < 10) {
|
|
||||||
shift_left(x);
|
|
||||||
exponent--;
|
|
||||||
}
|
|
||||||
//write back exponent
|
|
||||||
if (is_negative){
|
|
||||||
x->exponent = exponent | 0x8000;
|
|
||||||
} else {
|
|
||||||
x->exponent = exponent & 0x7fff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ensure MSdigit in MSdigit100 is > 0
|
||||||
|
if (x->lsu[0] < 10) {
|
||||||
|
shift_left(x);
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
//write back exponent
|
||||||
|
set_exponent(x, exponent, is_negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
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,11 +446,13 @@ 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);
|
||||||
_incr_exp(&tmp, get_exponent(acc));
|
if (get_exponent(acc) != get_exponent(&tmp)){
|
||||||
|
_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);
|
||||||
printf("incr_exp tmp: %s\n", buf);
|
printf(" incr_exp tmp: %s\n", buf);
|
||||||
#endif
|
#endif
|
||||||
//do subtraction
|
//do subtraction
|
||||||
for (i = DEC80_NUM_LSU - 1; i >=0; i--){
|
for (i = DEC80_NUM_LSU - 1; i >=0; i--){
|
||||||
@ -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
|
||||||
@ -542,22 +541,25 @@ void add_decn(dec80* acc, const dec80* x){
|
|||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
extern char buf[DECN_BUF_SIZE];
|
extern char buf[DECN_BUF_SIZE];
|
||||||
dec80_to_str(buf, acc);
|
dec80_to_str(buf, acc);
|
||||||
printf("rem_leading_zeros acc: %s\n", buf);
|
printf(" rem_leading_zeros acc: %s\n", buf);
|
||||||
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];
|
||||||
dec80_to_str(buf, acc);
|
dec80_to_str(buf, acc);
|
||||||
printf("incr_exp acc: %s\n", buf);
|
printf(" incr_exp acc: %s\n", buf);
|
||||||
dec80_to_str(buf, &tmp);
|
dec80_to_str(buf, &tmp);
|
||||||
printf("incr_exp tmp: %s\n", buf);
|
printf(" incr_exp tmp: %s\n", buf);
|
||||||
#endif
|
#endif
|
||||||
//do addition
|
//do addition
|
||||||
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user