diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-01-16 22:03:40 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-01-16 22:03:40 +0000 |
commit | dd36bc8f4acebbc891952073628b895ddd444388 (patch) | |
tree | 7deed3e87b9739df1dc773c9915034fbb41c71c9 /src/mpfr-mini-gmp.c | |
parent | b8ef4f9b79a2a989a601bf0fad918541aaada8cd (diff) | |
download | mpfr-dd36bc8f4acebbc891952073628b895ddd444388.tar.gz |
added two new files for mini-gmp interface
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@8754 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/mpfr-mini-gmp.c')
-rw-r--r-- | src/mpfr-mini-gmp.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/src/mpfr-mini-gmp.c b/src/mpfr-mini-gmp.c new file mode 100644 index 000000000..993f0509a --- /dev/null +++ b/src/mpfr-mini-gmp.c @@ -0,0 +1,322 @@ +/* mpfr-mini-gmp.c -- Interface functions for mini-gmp. + +Copyright 2014 Free Software Foundation, Inc. +Contributed by the AriC and Caramel projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef WANT_MINI_GMP + +#include "mpfr-impl.h" +#include "mpfr-mini-gmp.h" + +#ifndef mp_bits_per_limb +const int mp_bits_per_limb = GMP_NUMB_BITS; +#endif + +#ifdef WANT_gmp_randinit_default +void +gmp_randinit_default (gmp_randstate_t state) +{ +} +#endif + +#ifdef WANT_gmp_randseed_ui +void +gmp_randseed_ui (gmp_randstate_t state, const mpz_t seed) +{ + srand48 (mpz_get_ui (seed)); +} +#endif + +#ifdef WANT_gmp_randclear +void +gmp_randclear (gmp_randstate_t state) +{ +} +#endif + +#ifdef WANT_gmp_default_alloc +void * +gmp_default_alloc (size_t s) +{ + return malloc (s); +} +#endif + +#ifdef WANT_gmp_default_realloc +void * +gmp_default_realloc (void *x, size_t olds, size_t s) +{ + return realloc (x, s); +} +#endif + +#ifdef WANT_gmp_default_free +void +gmp_default_free (void *x, size_t s) +{ + free (x); +} +#endif + +#ifdef WANT_mpn_scan1 +mp_bitcnt_t +mpn_scan1 (const mp_limb_t *s, mp_bitcnt_t n) +{ + while (1) + { + if (s[n / GMP_NUMB_BITS] & ((mp_limb_t) 1 << (n % GMP_NUMB_BITS))) + return n; + n ++; + } +} +#endif + +#ifdef WANT_mpz_perfect_square_p +int +mpz_perfect_square_p (const mpz_t z) +{ + mpz_t s, r; + int ret; + + if (mpz_sgn (z) < 0) + return 0; + + mpz_init (s); + mpz_init (r); + mpz_sqrtrem (s, r, z); + ret = mpz_sgn (r) == 0; + mpz_clear (s); + mpz_clear (r); + return ret; +} +#endif + +#ifdef WANT_mpz_addmul_ui +void +mpz_addmul_ui (mpz_t a, const mpz_t b, unsigned long c) +{ + mpz_t t; + + mpz_init (t); + mpz_mul_ui (t, b, c); + mpz_add (a, a, t); + mpz_clear (t); +} +#endif + +#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; + + d->_mp_d = gmp_default_alloc (sizeof (mp_limb_t)); + 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); + MPFR_ASSERTN(q->_mp_size == nn + qxn); + mpn_copyi (qp, q->_mp_d, nn + qxn); + MPFR_ASSERTN(r->_mp_size == 1); + ret = r->_mp_d[0]; + mpz_clear (q); + mpz_clear (r); + if (qxn != 0) + mpz_clear (n); + return ret; +} +#endif + +#ifdef WANT_mpz_realloc2 +void +mpz_realloc2 (mpz_t X, mp_bitcnt_t N) +{ + unsigned long n = (N - 1) / GMP_NUMB_BITS + 1; + + if (n > X->_mp_alloc) + { + X->_mp_d = gmp_default_realloc (X->_mp_d, X->_mp_alloc, n); + X->_mp_alloc = n; + } +} +#endif + +#ifdef WANT_mpz_urandomb +void +mpz_urandomb (mpz_t ROP, gmp_randstate_t STATE, mp_bitcnt_t N) +{ + unsigned long n; + + mpz_realloc2 (ROP, N); + n = (N - 1) / GMP_NUMB_BITS + 1; /* number of limbs */ + while (n--) + ROP->_mp_d[n] = lrand48 (); +} +#endif + +#ifdef WANT_mpn_zero +void +mpn_zero (mp_limb_t *RP, mp_size_t N) +{ + memset (RP, 0, N * sizeof (mp_limb_t)); +} +#endif + +#ifdef WANT_mpn_popcount +mp_bitcnt_t +mpn_popcount (const mp_limb_t *S1P, mp_size_t N) +{ + mpz_t t; + + t->_mp_d = (mp_limb_t*) S1P; + t->_mp_size = N; + return mpz_popcount (t); +} +#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]; + MPFR_ASSERTN(r->_mp_size == dn); + mpn_copyi (np, r->_mp_d, dn); + mpz_clear (q); + mpz_clear (r); + return ret; +} +#endif + +#ifdef WANT_mpz_submul +void +mpz_submul (mpz_t ROP, const mpz_t OP1, const mpz_t OP2) +{ + mpz_t t; + + mpz_init (t); + mpz_mul (t, OP1, OP2); + mpz_sub (ROP, ROP, t); + mpz_clear (t); +} +#endif + +#ifdef WANT_mpz_addmul +void +mpz_addmul (mpz_t ROP, const mpz_t OP1, const mpz_t OP2) +{ + mpz_t t; + + mpz_init (t); + mpz_mul (t, OP1, OP2); + mpz_add (ROP, ROP, t); + mpz_clear (t); +} +#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); + MPFR_ASSERTN(r->_mp_size > 0); + mpn_copyi (RP, r->_mp_d, r->_mp_size); + mpz_clear (q); + mpz_clear (r); +} +#endif + +#ifdef WANT_mpn_sqrtrem +mp_size_t +mpn_sqrtrem (mp_limb_t *SP, mp_limb_t *RP, const mp_limb_t *NP, mp_size_t N) +{ + mpz_t s, r, n; + mp_size_t sn = (N + 1) >> 1, ret; + + n->_mp_d = (mp_limb_t*) NP; + n->_mp_size = N; + mpz_init (s); + mpz_init (r); + mpz_sqrtrem (s, r, n); + if (s->_mp_size > 0) + mpn_copyi (SP, s->_mp_d, s->_mp_size); + if (s->_mp_size < sn) + mpn_zero (SP + s->_mp_size, sn - s->_mp_size); + if (r->_mp_size > 0) + mpn_copyi (RP, r->_mp_d, r->_mp_size); + ret = r->_mp_size; + mpz_clear (s); + mpz_clear (r); + return ret; +} +#endif + +#ifdef WANT_mpz_dump +void +mpz_dump (mpz_t z) +{ + mpz_out_str (stdout, 10, z); + putchar ('\n'); +} +#endif + +#endif /* WANT_MINI_GMP */ |