Pergunta

Acabei de descobrir, para o meu constrangimento, que alimentar expoentes negativos para mpz_pow_ui não funciona muito bem. ("O manual diz não assinado por muito tempo, você sabe.") Para o outro mpz_pow Funções, o manual usa conceitos que não entendo. Por exemplo "base^Exp mod mod" na sequência:

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.

No código a seguir, o que devo mudar para tornar capaz de lidar com expoentes negativos?

#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;
}
Foi útil?

Solução

o mpz_t Tipo de dados pode armazenar apenas números inteiros e 2-18 não é um número inteiro. Para calcular isso, você terá que usar o tipo de ponto flutuante mpf_t ou o tipo de número racional mpq_t.

Outras dicas

Não vou cortar o código para você, mas farei você ciente de que:

2-n = 1/2n

Então você pode simplesmente passar no expoente positivo e dividir 1 por esse número (e escolher um tipo não inteiro como mpf_t - a mpz_t O tipo é integrante, portanto não pode representar números reais como 2-18).

Eu não sei muito sobre GMP, mas:

2 ^ -18

é equivalente a:

1 / (2 ^ 18)

Então, por que não escrever uma função que lida com expoentes negativos dessa maneira?

Exp negativo é suportado se existir um mod de Base-1 inverso-1 (consulte MPZ_invert na Seção 5.9 [Funções Teóricas do Número], página 35). Se um inverso não existe, uma divisão por zero será levantada.

Se você está falando sobre isso, isso envolve a teoria dos números. A divisão, ou mais precisamente inversa de multplicação, existe apenas em determinadas condições. Não me lembro exatamente das regras, mas basicamente está dizendo que a operação da divisão não funcionará se Base-1 mod mod não existe.

O que você precisa fazer depende do que você quer que aconteça com os bits que perderão na operação. Como você está lidando com números inteiros, elevar uma divisão negativa implica na divisão (bem, reciprocidade), mas o GMP oferece várias formas de divisão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top