How does one calculate 2 ^ -18 using GMP?
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;
}
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.