diff options
author | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2016-12-30 07:56:52 +0100 |
---|---|---|
committer | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2016-12-30 07:56:52 +0100 |
commit | ad7bd8ca59f4d6614e6bc980f931c69a581fee7e (patch) | |
tree | c3d6205b5974a9b8b2faad6caea65c5debf261e8 /tune/common.c | |
parent | 84dc1bbab976aa9cc2bc6bd49e62a565591e9be4 (diff) | |
download | gmp-ad7bd8ca59f4d6614e6bc980f931c69a581fee7e.tar.gz |
tune/: support mpz_invert
Diffstat (limited to 'tune/common.c')
-rw-r--r-- | tune/common.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/tune/common.c b/tune/common.c index a794aafe6..41a1860da 100644 --- a/tune/common.c +++ b/tune/common.c @@ -2039,6 +2039,47 @@ speed_mpz_add (struct speed_params *s) } +/* An inverse (s->r) or (s->size)/2 modulo s->size limbs */ + +double +speed_mpz_invert (struct speed_params *s) +{ + mpz_t a, m, r; + mp_size_t k; + unsigned i; + double t; + + if (s->r == 0) + k = s->size/2; + else if (s->r < GMP_LIMB_HIGHBIT) + k = s->r; + else /* s->r < 0 */ + k = s->size - (-s->r); + + SPEED_RESTRICT_COND (k > 0 && k <= s->size); + + mpz_init_set_n (m, s->yp, s->size); + mpz_setbit (m, 0); /* force m to odd */ + + mpz_init_set_n (a, s->xp, k); + + mpz_init (r); + while (mpz_invert (r, a, m) == 0) + mpz_add_ui (a, a, 1); + + speed_starttime (); + i = s->reps; + do + mpz_invert (r, a, m); + while (--i != 0); + t = speed_endtime (); + + mpz_clear (r); + mpz_clear (a); + mpz_clear (m); + return t; + } + /* If r==0, calculate binomial(size,size/2), otherwise calculate binomial(size,r). */ |