summaryrefslogtreecommitdiff
path: root/mpz/tdiv_q_ui.c
diff options
context:
space:
mode:
authortege <tege@gmplib.org>2002-04-19 15:30:43 +0200
committertege <tege@gmplib.org>2002-04-19 15:30:43 +0200
commit820a8c8b40d7455580f623e3eeb13493c16a23d7 (patch)
treecb33eea6b94e1155b813bcc236d7ae93afc69a39 /mpz/tdiv_q_ui.c
parent07ac210a6d447146d6b34ad6e559ff83501d294a (diff)
downloadgmp-820a8c8b40d7455580f623e3eeb13493c16a23d7.tar.gz
Nailify.
Diffstat (limited to 'mpz/tdiv_q_ui.c')
-rw-r--r--mpz/tdiv_q_ui.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/mpz/tdiv_q_ui.c b/mpz/tdiv_q_ui.c
index ccca2bfb9..4a84cdd0e 100644
--- a/mpz/tdiv_q_ui.c
+++ b/mpz/tdiv_q_ui.c
@@ -26,28 +26,53 @@ MA 02111-1307, USA. */
unsigned long int
mpz_tdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
{
- mp_size_t dividend_size;
- mp_size_t size;
- mp_ptr quot_ptr;
- mp_limb_t remainder_limb;
+ mp_size_t ns, nn, qn;
+ mp_ptr np, qp;
+ mp_limb_t rl;
if (divisor == 0)
DIVIDE_BY_ZERO;
- dividend_size = dividend->_mp_size;
- size = ABS (dividend_size);
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(quot) = 0;
+ return 0;
+ }
- if (quot->_mp_alloc < size)
- _mpz_realloc (quot, size);
+ nn = ABS(ns);
+ MPZ_REALLOC (quot, nn);
+ qp = PTR(quot);
+ np = PTR(dividend);
- quot_ptr = quot->_mp_d;
+#if GMP_NAIL_BITS != 0
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+ TMP_DECL (mark);
- remainder_limb
- = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size, (mp_limb_t) divisor);
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ SIZ(quot) = 0;
+ rl = np[0];
+ return rl;
+ }
- /* The quotient is SIZE limbs, but the most significant might be zero. */
- size -= size != 0 && quot_ptr[size - 1] == 0;
- quot->_mp_size = dividend_size >= 0 ? size : -size;
+ TMP_MARK (mark);
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
+ TMP_FREE (mark);
+ rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
+ qn = nn - 2 + 1; qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
+ }
+ else
+#endif
+ {
+ rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
+ qn = nn - (qp[nn - 1] == 0);
+ }
- return remainder_limb;
+ SIZ(quot) = ns >= 0 ? qn : -qn;
+ return rl;
}