summaryrefslogtreecommitdiff
path: root/mpz/fdiv_r_ui.c
diff options
context:
space:
mode:
authortege <tege@gmplib.org>2002-04-20 16:42:23 +0200
committertege <tege@gmplib.org>2002-04-20 16:42:23 +0200
commit3c7d00eb181e32917f7e8aac2d94f0ffde56056b (patch)
tree31732a62b53c3e1dfcc3afcabbc5e26f25d646c2 /mpz/fdiv_r_ui.c
parent145ab235c286e4cacc64909886cbec3b217ce13b (diff)
downloadgmp-3c7d00eb181e32917f7e8aac2d94f0ffde56056b.tar.gz
Nailify.
Diffstat (limited to 'mpz/fdiv_r_ui.c')
-rw-r--r--mpz/fdiv_r_ui.c73
1 files changed, 62 insertions, 11 deletions
diff --git a/mpz/fdiv_r_ui.c b/mpz/fdiv_r_ui.c
index 38b60a7c5..5c39e8caa 100644
--- a/mpz/fdiv_r_ui.c
+++ b/mpz/fdiv_r_ui.c
@@ -26,23 +26,74 @@ MA 02111-1307, USA. */
unsigned long int
mpz_fdiv_r_ui (mpz_ptr rem, 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;
if (divisor == 0)
DIVIDE_BY_ZERO;
- dividend_size = dividend->_mp_size;
- size = ABS (dividend_size);
+ ns = SIZ(dividend);
+ if (ns == 0)
+ {
+ SIZ(rem) = 0;
+ return 0;
+ }
- remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+ nn = ABS(ns);
+ np = PTR(dividend);
+#if GMP_NAIL_BITS != 0
+ if (divisor > GMP_NUMB_MAX)
+ {
+ mp_limb_t dp[2];
+ mp_ptr rp, qp;
+ mp_size_t rn;
+ TMP_DECL (mark);
- if (remainder_limb != 0 && dividend_size < 0)
- remainder_limb = divisor - remainder_limb;
+ MPZ_REALLOC (rem, 2);
+ rp = PTR(rem);
- rem->_mp_d[0] = remainder_limb;
- rem->_mp_size = remainder_limb != 0;
+ 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);
+ }
- return remainder_limb;
+ 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);
+ SIZ(rem) = rn;
+ }
+ else
+#endif
+ {
+ rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor);
+ if (rl == 0)
+ SIZ(rem) = 0;
+ else
+ {
+ if (ns < 0)
+ rl = divisor - rl;
+
+ PTR(rem)[0] = rl;
+ SIZ(rem) = 1;
+ }
+ }
+
+ return rl;
}