void m_apm_integer_divide(M_APM rr, M_APM aa, M_APM bb) { /* * we must use this divide function since the * faster divide function using the reciprocal * will round the result (possibly changing * nnm.999999... --> nn(m+1).0000 which would * invalidate the 'integer_divide' goal). */ if (aa->m_apm_error || bb->m_apm_error) { M_set_to_error(rr); return; } M_apm_sdivide(rr, 4, aa, bb); if (rr->m_apm_exponent <= 0) /* result is 0 */ { M_set_to_zero(rr); } else { if (rr->m_apm_datalength > rr->m_apm_exponent) { rr->m_apm_datalength = rr->m_apm_exponent; M_apm_normalize(rr); } } }
void m_apm_divide(M_APM rr, int places, M_APM aa, M_APM bb) { M_APM tmp0, tmp1; int sn, nexp, dplaces; sn = aa->m_apm_sign * bb->m_apm_sign; if (sn == 0) /* one number is zero, result is zero */ { if (bb->m_apm_sign == 0) { M_apm_log_error_msg(M_APM_RETURN, "Warning! ... \'m_apm_divide\', Divide by 0"); } M_set_to_zero(rr); return; } /* * Use the original 'Knuth' method for smaller divides. On the * author's system, this was the *approx* break even point before * the reciprocal method used below became faster. */ if (places < 250) { M_apm_sdivide(rr, places, aa, bb); return; } /* mimic the decimal place behavior of the original divide */ nexp = aa->m_apm_exponent - bb->m_apm_exponent; if (nexp > 0) dplaces = nexp + places; else dplaces = places; tmp0 = M_get_stack_var(); tmp1 = M_get_stack_var(); m_apm_reciprocal(tmp0, (dplaces + 8), bb); m_apm_multiply(tmp1, tmp0, aa); m_apm_round(rr, dplaces, tmp1); M_restore_stack(2); }