From 14251c91cb2b82d783dd9ded477e9ab71c5f8615 Mon Sep 17 00:00:00 2001 From: Jeff Wang Date: Wed, 27 Mar 2019 03:53:18 -0400 Subject: [PATCH] multiplication --- src/decn/decn.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ src/decn/decn.h | 1 + 2 files changed, 65 insertions(+) diff --git a/src/decn/decn.c b/src/decn/decn.c index dfa40e1..a971942 100644 --- a/src/decn/decn.c +++ b/src/decn/decn.c @@ -9,12 +9,14 @@ //#define DEBUG //#define DEBUG_ADD +#define DEBUG_MULT //#define DEBUG_COMPARE_MAGN #ifndef DESKTOP #undef DEBUG #undef DEBUG_ADD #undef DEBUG_COMPARE_MAGN +#undef DEBUG_MULT #endif #ifdef DESKTOP @@ -587,6 +589,68 @@ void add_decn(dec80* acc, const dec80* x){ } } +void mult_decn(dec80* acc, const dec80* x){ + dec80 tmp; //copy of x + dec80 acc_tmp; //holds sum + int8_t i, j; + uint8_t carry = 0; + uint8_t is_neg; + //initialize values + copy_decn(&tmp, x); + set_dec80_zero(&acc_tmp); + //normalize + remove_leading_zeros(acc); + remove_leading_zeros(&tmp); + //calculate new exponent + if ((acc->exponent & 0x8000) ^ (tmp.exponent & 0x8000)){ //signs differ + is_neg = 1; + } else { + is_neg = 0; + } + acc_tmp.exponent = get_exponent(acc) + get_exponent(&tmp); + if (is_neg){ + acc_tmp.exponent |= 0x8000; + } else { + acc_tmp.exponent &= 0x7fff; + } + //do multiply + for (i = DEC80_NUM_LSU - 1; i >= 0; i--){ + //partial product + for (j = DEC80_NUM_LSU - 1; j >= 0; j--){ + uint16_t digit100 = acc_tmp.lsu[j] + (tmp.lsu[i] * acc->lsu[j]) + carry; + acc_tmp.lsu[j] = digit100 % 100; + carry = digit100 / 100; + assert(carry < 100); + } +#ifdef DEBUG_MULT + printf("\n%d:", i); + printf("\n acc:"); + for (j = 0; j < DEC80_NUM_LSU; j++){ + printf(" %3d", acc->lsu[j]); + } + printf("\n x:"); + for (j = 0; j < DEC80_NUM_LSU; j++){ + if (j == i) + printf(" %3d", tmp.lsu[j]); + else + printf(" "); + } + printf("\n acc_tmp:"); + for (j = 0; j < DEC80_NUM_LSU; j++){ + printf(" %3d", acc_tmp.lsu[j]); + } + printf("\ncarry:%d", carry); +#endif + //shift + shift_right(&acc_tmp); + shift_right(&acc_tmp); + //add back carry to MSdigit100 + acc_tmp.lsu[0] = carry; //was 0 from shift + } + //copy back to acc + copy_decn(acc, &acc_tmp); +} + //buf should hold at least 18 + 4 + 5 + 1 = 28 void dec80_to_str(char* buf, const dec80* x){ uint8_t i = 0; diff --git a/src/decn/decn.h b/src/decn/decn.h index 7f85640..24510b2 100644 --- a/src/decn/decn.h +++ b/src/decn/decn.h @@ -38,6 +38,7 @@ void set_dec80_NaN(dec80* dest); void negate_decn(dec80* x); int8_t compare_decn(dec80* a, dec80* b); //ab: 1 void add_decn(dec80* acc, const dec80* x); +void mult_decn(dec80* acc, const dec80* x); //buf should hold at least 18 + 4 + 5 + 1 = 28 #define DECN_BUF_SIZE 28