Niels, > > The most wanted are the mpn division functions, I wonder why those functions > > are not exported. > > I think the main reason is that the interface of the internal division > functions in mini-gmp, in particular mpn_div_qr, is quite different from > the older interface used in gmp. And gmp is slowly moving towards an > interface more like the one in mini-gmp. So when the real gmp gets a > public function mpn_div_qr, mini-gmp's version should also be exported, > and we should make sure that it's compatible. > > Precisely which division functions are you missing? mpn_tdiv_qr? It > would make some sense to add an mpn_tdiv_qr to mini-gmp, as a small > wrapper around mpn_div_qr.
I know the division interface will change for GMP 6 :-) Here are the division functions I had to re-implement on top of mini-gmp (I know mpn_divrem is obsolete, but its interface is better suited for MPFR): #ifdef WANT_mpn_divrem_1 mp_limb_t mpn_divrem_1 (mp_limb_t *qp, mp_size_t qxn, mp_limb_t *np, mp_size_t nn, mp_limb_t d0) { mpz_t q, r, n, d; mp_limb_t ret, dd[1]; d->_mp_d = dd; d->_mp_d[0] = d0; d->_mp_size = 1; mpz_init (q); mpz_init (r); if (qxn == 0) { n->_mp_d = np; n->_mp_size = nn; } else { mpz_init2 (n, (nn + qxn) * GMP_NUMB_BITS); mpn_copyi (n->_mp_d + qxn, np, nn); mpn_zero (n->_mp_d, qxn); n->_mp_size = nn + qxn; } mpz_tdiv_qr (q, r, n, d); if (q->_mp_size > 0) mpn_copyi (qp, q->_mp_d, q->_mp_size); if (q->_mp_size < nn + qxn) mpn_zero (qp + q->_mp_size, nn + qxn - q->_mp_size); ret = (r->_mp_size == 1) ? r->_mp_d[0] : 0; mpz_clear (q); mpz_clear (r); if (qxn != 0) mpz_clear (n); return ret; } #endif #ifdef WANT_mpn_divrem mp_limb_t mpn_divrem (mp_limb_t *qp, mp_size_t qn, mp_limb_t *np, mp_size_t nn, const mp_limb_t *dp, mp_size_t dn) { mpz_t q, r, n, d; mp_limb_t ret; MPFR_ASSERTN(qn == 0); qn = nn - dn; n->_mp_d = np; n->_mp_size = nn; d->_mp_d = (mp_limb_t*) dp; d->_mp_size = dn; mpz_init (q); mpz_init (r); mpz_tdiv_qr (q, r, n, d); MPFR_ASSERTN(q->_mp_size == qn || q->_mp_size == qn + 1); mpn_copyi (qp, q->_mp_d, qn); ret = (q->_mp_size == qn) ? 0 : q->_mp_d[qn]; if (r->_mp_size > 0) mpn_copyi (np, r->_mp_d, r->_mp_size); if (r->_mp_size < dn) mpn_zero (np + r->_mp_size, dn - r->_mp_size); mpz_clear (q); mpz_clear (r); return ret; } #endif #ifdef WANT_mpn_tdiv_qr void mpn_tdiv_qr (mp_limb_t *QP, mp_limb_t *RP, mp_size_t QXN, const mp_limb_t *NP, mp_size_t NN, const mp_limb_t *DP, mp_size_t DN) { mpz_t q, r, n, d; MPFR_ASSERTN(QXN == 0); n->_mp_d = (mp_limb_t*) NP; n->_mp_size = NN; d->_mp_d = (mp_limb_t*) DP; d->_mp_size = DN; mpz_init (q); mpz_init (r); mpz_tdiv_qr (q, r, n, d); MPFR_ASSERTN(q->_mp_size > 0); mpn_copyi (QP, q->_mp_d, q->_mp_size); if (q->_mp_size < NN - DN + 1) mpn_zero (QP + q->_mp_size, NN - DN + 1 - q->_mp_size); if (r->_mp_size > 0) mpn_copyi (RP, r->_mp_d, r->_mp_size); if (r->_mp_size < DN) mpn_zero (RP + r->_mp_size, DN - r->_mp_size); mpz_clear (q); mpz_clear (r); } #endif Paul _______________________________________________ gmp-devel mailing list gmp-devel@gmplib.org https://gmplib.org/mailman/listinfo/gmp-devel