Question

I've just discovered, to my embarrassment, that feeding negative exponents to mpz_pow_ui doesn't work very well. ("The manual does say unsigned long, you know.") For the other mpz_pow functions, the manual uses concepts I don't understand. For example "base^exp mod mod" in the following:

void mpz_powm (mpz_t rop, mpz_t base, mpz_t exp, mpz_t mod) 
void mpz_powm_ui (mpz_t rop, mpz_t base, unsigned long int exp, mpz_t mod)
Set _rop_ to _base_^_exp_ mod _mod_.
Negative exp is supported if an inverse base-1 mod mod exists (see mpz_invert in Section 5.9 [Number Theoretic Functions], page 35). If an inverse doesn’t exist then a divide by zero is raised.

In the following code, what do I have to change to make it able to handle negative exponents?

#define Z(x) mpz_t x; mpz_init( x );

BSTR __stdcall IBIGPOWER(BSTR p1, long p2 ) {
    USES_CONVERSION;

    Z(n1);
    Z(res);

    LPSTR sNum1 = W2A( p1 );

    mpz_set_str( n1, sNum1, 10 );

    mpz_pow_ui( res, n1, p2 );

    char * buff =  (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 );

    mpz_get_str(buff, 10, res);

    BSTR bResult = _com_util::ConvertStringToBSTR( buff );
    return bResult;
}
Was it helpful?

Solution

The mpz_t data type can only store integers, and 2-18 is not an integer. To calculate that, you'll have to use the floating-point type mpf_t or the rational number type mpq_t.

OTHER TIPS

I won't cut the code for you but I will make you aware that:

2-n = 1/2n

So you can just pass the positive exponent then divide 1 by that number (and choose a non-integer type like mpf_t - the mpz_t type is integral so cannot represent real numbers like 2-18).

I don't know much about GMP but:

2 ^ -18

is equivalent to:

1 / (2 ^ 18)

So why not write a function that handles negative exponents in this way?

Negative exp is supported if an inverse base-1 mod mod exists (see mpz_invert in Section 5.9 [Number Theoretic Functions], page 35). If an inverse doesn’t exist then a divide by zero is raised.

If you're talking about that, that's involves number theory. Division, or more precisely inverse of multplication, only exists on certain conditions. I don't exactly remember the rules, but basically it's saying that the division operation won't work if base-1 mod mod doesn't exist.

What you need to do depends on what you want to happen with the bits that will lost in the operation. Since you are dealing with integers, raising to a negative power implies division (well, reciprocation), but GMP offers several forms of division.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top