5

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;
}
bugmagnet
  • 7,631
  • 8
  • 69
  • 131

5 Answers5

10

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).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
8

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.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
2

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?

Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
2

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.

Calyth
  • 1,673
  • 3
  • 16
  • 26
0

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.

Doug Currie
  • 40,708
  • 1
  • 95
  • 119