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;
}
È stato utile?

Soluzione

Il tipo di dati mpz_t può solo memorizzare numeri interi e 2 -18 non è un numero intero. Per calcolarlo, dovrai usare il tipo a virgola mobile mpf_t o il tipo di numero razionale mpq_t .

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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top