Daniel S.
Daniel S.

Reputation: 6640

Is there a good reason why there's no mpz_tdiv_r_2exp_ui() in GMP?

GMP is a fast arbitrary precision maths library. I use it for integer arithmetic.

There are many functions for integer divisions and remainders, but I'm missing

unsigned long int mpz_tdiv_r_2exp_ui(const mpz_t n, mp_bitcnt_t b)

Is there any reason why it's not there?

And btw, why does the existing

unsigned long int mpz_tdiv_r_ui(mpz_t r, const mpz_t n, unsigned long int d);

require mpz_t r as the argument to take the result, while the result is guaranteed to fit into an unsigned long int AND this is already returned? That seems to be an unnecessary performance loss. (Just note that the doc is wrong in "in fact returning the remainder is all the div_ui functions do". That's wrong, because mpz_tdiv_r_ui() also modifies r (as you would expect)).

Is there any reason for these odd things? If not, then I'll make a change request.

Upvotes: 1

Views: 81

Answers (1)

Marc Glisse
Marc Glisse

Reputation: 7925

I'm missing

unsigned long int mpz_tdiv_r_2exp_ui(const mpz_t n, mp_bitcnt_t b)

Is there any reason why it's not there?

GMP has _ui functions for when the argument is a small integer, and _2exp functions for when the argument is a power of 2, but I don't believe it provides any specific function for small powers of 2. If you have a need (and it helps if a prototype shows an interesting performance win, although it may not be required), you should post on the gmp-discuss mailing-list to suggest this new API. I am not sure how it should be named though, _2exp_ui looks like there are 2 arguments, one of which is a power of 2 and the other a small integer. mpz_and_ui could be an alternative, but at that point it seems simpler to extract the low bits with mpz_get_ui and work with the resulting unsigned long, a specialized function is unlikely to be significantly faster.

why does the existing

unsigned long int mpz_tdiv_r_ui(mpz_t r, const mpz_t n, unsigned long int d);

require mpz_t r as the argument to take the result, while the result is guaranteed to fit into an unsigned long int AND this is already returned?

For mpz_tdiv_r_ui, the return value is the absolute value of the remainder, which may be positive or negative, so it is missing information and we need something else (well, we can easily deduce the sign from the input, the harder case would be rounding to nearest, which is not provided). It is convenient to keep the interface consistent. If the cost of updating r is too much for you, there is the function mpz_tdiv_ui (see below).

the doc is wrong in "in fact returning the remainder is all the div_ui functions do". That's wrong, because mpz_tdiv_r_ui() also modifies r (as you would expect)

This sentence is about the function unsigned long int mpz_tdiv_ui (const mpz_t n, unsigned long int d) (no r or q after div). That function does return the remainder and does not have any r to update, just as the doc says.

Upvotes: 1

Related Questions