Question

Je viens de découvrir, à mon grand embarras, que l'alimentation des exposants négatifs dans mpz_pow_ui ne fonctionne pas très bien. ("Le manuel dit que vous devez signer longtemps, vous savez.") Pour les autres fonctions mpz_pow , le manuel utilise des concepts que je ne comprends pas. Par exemple, base ^ exp mod mod " dans ce qui suit:

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.

Dans le code suivant, que dois-je changer pour le rendre capable de gérer les exposants négatifs?

#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;
}
Était-ce utile?

La solution

Le type de données mpz_t ne peut stocker que des entiers et 2 -18 n'est pas un entier. Pour calculer cela, vous devez utiliser le type à virgule flottante mpf_t ou le type de numéro rationnel mpq_t .

Autres conseils

Je ne couperai pas le code pour vous, mais je vous ferai savoir que:

2 -n = 1 / 2 n

Donc, vous pouvez simplement passer l'exposant positif puis diviser 1 par ce nombre (et choisir un type non entier tel que mpf_t - le type mpz_t est intégral et ne peut donc pas représenter nombres réels tels que 2 -18 ).

Je ne connais pas grand chose aux BPF mais:

2 ^ -18

est équivalent à:

1 / (2 ^ 18)

Alors pourquoi ne pas écrire une fonction qui gère les exposants négatifs de cette manière?

  

Exp négatif est pris en charge si un   le mod inverse base-1 existe (voir   mpz_invert dans la section 5.9 [Nombre   Fonctions théoriques], page 35). Si un   l’inverse n’existe pas alors une division par   zéro est élevé.

Si vous parlez de cela, cela implique la théorie des nombres. La division, ou plus précisément l'inverse de la multiplication, n'existe que sous certaines conditions. Je ne me souviens pas exactement des règles, mais en gros, cela signifie que l'opération de division ne fonctionnera pas si le base-1 mod mod n'existe pas.

Ce que vous devez faire dépend de ce que vous voulez faire avec les bits perdus lors de l'opération. Puisque vous avez affaire à des entiers, augmenter le pouvoir négatif implique une division (bien sûr, réciprocité), mais GMP propose plusieurs formes de division .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top