fix division: make recip operate on accum
also avoids extra copy when only taking recip
This commit is contained in:
parent
8e9f37c7d2
commit
a3b00dd815
@ -769,12 +769,9 @@ void recip_decn(void){
|
|||||||
#define X_COPY Tmp3Decn //holds copy of original x
|
#define X_COPY Tmp3Decn //holds copy of original x
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
exp_t initial_exp;
|
exp_t initial_exp;
|
||||||
//denominator is already in BDecn for division, but x is in Accum for 1/x
|
|
||||||
// copy accum to be for 1/x case
|
|
||||||
copy_decn(&BDecn, &AccDecn);
|
|
||||||
//check divide by zero
|
//check divide by zero
|
||||||
#ifdef EXTRA_CHECKS
|
#ifdef EXTRA_CHECKS
|
||||||
if (decn_is_zero(&BDecn)){
|
if (decn_is_zero(&AccDecn)){
|
||||||
set_dec80_NaN(&AccDecn);
|
set_dec80_NaN(&AccDecn);
|
||||||
#ifdef DESKTOP
|
#ifdef DESKTOP
|
||||||
printf("error division by 0\n");
|
printf("error division by 0\n");
|
||||||
@ -784,11 +781,10 @@ void recip_decn(void){
|
|||||||
#endif
|
#endif
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(&AccDecn);
|
remove_leading_zeros(&AccDecn);
|
||||||
remove_leading_zeros(&BDecn);
|
|
||||||
//store copy of x
|
//store copy of x
|
||||||
copy_decn(&X_COPY, &BDecn);
|
copy_decn(&X_COPY, &AccDecn);
|
||||||
//get initial exponent of estimate for 1/x
|
//get initial exponent of estimate for 1/x
|
||||||
initial_exp = get_exponent(&BDecn);
|
initial_exp = get_exponent(&AccDecn);
|
||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
printf("exponent %d", initial_exp);
|
printf("exponent %d", initial_exp);
|
||||||
#endif
|
#endif
|
||||||
@ -797,13 +793,13 @@ void recip_decn(void){
|
|||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
printf(" -> %d\n", initial_exp);
|
printf(" -> %d\n", initial_exp);
|
||||||
#endif
|
#endif
|
||||||
set_exponent(&CURR_RECIP, initial_exp, (BDecn.exponent < 0)); //set exponent, copy sign
|
set_exponent(&CURR_RECIP, initial_exp, (AccDecn.exponent < 0)); //set exponent, copy sign
|
||||||
//get initial estimate for 1/x
|
//get initial estimate for 1/x
|
||||||
if (BDecn.lsu[0] < 20){ //mantissa between 1 and 2
|
if (AccDecn.lsu[0] < 20){ //mantissa between 1 and 2
|
||||||
CURR_RECIP.lsu[0] = 50; //0.50 with implicit point and exponent
|
CURR_RECIP.lsu[0] = 50; //0.50 with implicit point and exponent
|
||||||
} else if (BDecn.lsu[0] < 33){
|
} else if (AccDecn.lsu[0] < 33){
|
||||||
CURR_RECIP.lsu[0] = 30;
|
CURR_RECIP.lsu[0] = 30;
|
||||||
} else if (BDecn.lsu[0] < 50){
|
} else if (AccDecn.lsu[0] < 50){
|
||||||
CURR_RECIP.lsu[0] = 20;
|
CURR_RECIP.lsu[0] = 20;
|
||||||
} else {
|
} else {
|
||||||
CURR_RECIP.lsu[0] = 10; //0.1 with implicit point and exponent
|
CURR_RECIP.lsu[0] = 10; //0.1 with implicit point and exponent
|
||||||
@ -856,6 +852,7 @@ inline void div_decn(void){
|
|||||||
#define ACC_COPY Tmp4Decn //holds copy of original acc
|
#define ACC_COPY Tmp4Decn //holds copy of original acc
|
||||||
//store copy of acc for final multiply by 1/x
|
//store copy of acc for final multiply by 1/x
|
||||||
copy_decn(&ACC_COPY, &AccDecn);
|
copy_decn(&ACC_COPY, &AccDecn);
|
||||||
|
copy_decn(&AccDecn, &BDecn);
|
||||||
recip_decn();
|
recip_decn();
|
||||||
//Accum now holds 1/x, multiply by original acc to complete division
|
//Accum now holds 1/x, multiply by original acc to complete division
|
||||||
copy_decn(&BDecn, &ACC_COPY);
|
copy_decn(&BDecn, &ACC_COPY);
|
||||||
@ -866,6 +863,7 @@ inline void div_decn(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//constants used for ln(x) and exp(x)
|
//constants used for ln(x) and exp(x)
|
||||||
#define NUM_A_ARR 9
|
#define NUM_A_ARR 9
|
||||||
static const dec80 LN_A_ARR[NUM_A_ARR] = {
|
static const dec80 LN_A_ARR[NUM_A_ARR] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user