summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortege <tege@gmplib.org>2002-04-20 17:22:42 +0200
committertege <tege@gmplib.org>2002-04-20 17:22:42 +0200
commit040efe5fa0320fdb0fe5e7c74a79b8e186cb8090 (patch)
tree8223be18c4b3f1f75bc56a76e168f4f7d6bb9321
parent524b4d72d5ec56a36d2389e8ccde72df3c8ed59a (diff)
downloadgmp-040efe5fa0320fdb0fe5e7c74a79b8e186cb8090.tar.gz
Nailify.
-rw-r--r--mpz/fdiv_ui.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/mpz/fdiv_ui.c b/mpz/fdiv_ui.c
index e73cd4554..f680fe822 100644
--- a/mpz/fdiv_ui.c
+++ b/mpz/fdiv_ui.c
@@ -26,17 +26,66 @@ MA 02111-1307, USA. */
unsigned long int
mpz_fdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
{
- mp_size_t dividend_size;
- mp_size_t size;
- mp_limb_t remainder_limb;
+ mp_size_t ns, nn;
+ mp_ptr np;
+ mp_limb_t rl;
- dividend_size = dividend->_mp_size;
- size = ABS (dividend_size);
+ if (divisor == 0)
+ DIVIDE_BY_ZERO;
- remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ return 0;
+ }
- if (remainder_limb != 0 && dividend_size < 0)
- remainder_limb = divisor - remainder_limb;
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if GMP_NAIL_BITS != 0
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2], rp[2];
+ mp_ptr qp;
+ mp_size_t rn;
+ TMP_DECL (mark);
- return remainder_limb;
+ if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
+ {
+ rl = np[0];
+ rp[0] = rl;
+ }
+ else
+ {
+ TMP_MARK (mark);
+ dp[0] = divisor & GMP_NUMB_MASK;
+ dp[1] = divisor >> GMP_NUMB_BITS;
+ qp = TMP_ALLOC_LIMBS (nn - 2 + 1);
+ 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);
+ }
+
+ if (rl != 0 && ns < 0)
+ {
+ rl = divisor - rl;
+ rp[0] = rl & GMP_NUMB_MASK;
+ rp[1] = rl >> GMP_NUMB_BITS;
+ }
+
+ rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ ;
+ else
+ {
+ if (ns < 0)
+ rl = divisor - rl;
+ }
+ }
+
+ return rl;
}