Domanda
Ho appena scoperto, con mio imbarazzo, che alimentare esponenti negativi in ?? mpz_pow_ui
non funziona molto bene. (" Il manuale dice unsigned long, lo sai. ") Per le altre funzioni mpz_pow
, il manuale usa concetti che non capisco. Ad esempio " base ^ exp mod mod " nel seguito:
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.
Nel seguente codice, cosa devo modificare per renderlo in grado di gestire esponenti negativi?
#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;
}
Altri suggerimenti
Non taglierò il codice per te ma ti farò sapere che:
2 -n = 1/2n
Quindi puoi semplicemente passare l'esponente positivo quindi dividere 1 per quel numero (e scegliere un tipo non intero come mpf_t
- il tipo mpz_t
è integrale quindi non può rappresentare numeri reali come 2-18
).
Non so molto di GMP ma:
2 ^ -18
è equivalente a:
1 / (2 ^ 18)
Quindi perché non scrivere una funzione che gestisca esponenti negativi in ??questo modo?
Exp negativo è supportato se un esiste mod mod base-1 inversa (vedi mpz_invert nella Sezione 5.9 [Numero Funzioni teoriche], pagina 35). Se uno l'inverso non esiste quindi una divisione per lo zero viene generato.
Se ne parli, ciò implica la teoria dei numeri. La divisione, o più precisamente l'inverso della moltiplicazione, esiste solo a determinate condizioni. Non ricordo esattamente le regole, ma fondamentalmente sta dicendo che l'operazione di divisione non funzionerà se base-1 mod mod non esiste.
Quello che devi fare dipende da cosa vuoi che accada con i bit che andranno persi durante l'operazione. Dato che hai a che fare con numeri interi, elevare a un potere negativo implica divisione (beh, reciprocità), ma GMP offre diverse forme di divisione .