Pregunta

Acabo de descubrir, para mi vergüenza, que alimentar exponentes negativos a mpz_pow_ui no funciona muy bien. (" El manual dice que no está firmado por mucho tiempo, ya sabes. ") Para las otras funciones mpz_pow , el manual utiliza conceptos que no entiendo. Por ejemplo, " base ^ exp mod mod " en lo siguiente:

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.

En el siguiente código, ¿qué debo cambiar para que sea capaz de manejar exponentes 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;
}
¿Fue útil?

Solución

El tipo de datos mpz_t solo puede almacenar números enteros, y 2 -18 no es un número entero. Para calcular eso, deberá utilizar el tipo de punto flotante mpf_t o el tipo de número racional mpq_t .

Otros consejos

No cortaré el código por ti, pero te avisaré de que:

2 -n = 1/2n

Así que solo puedes pasar el exponente positivo y luego dividir 1 por ese número (y elegir un tipo no entero como mpf_t - el tipo mpz_t es integral, por lo que no puede representar números reales como 2-18 ).

No sé mucho sobre GMP pero:

2 ^ -18

es equivalente a:

1 / (2 ^ 18)

Entonces, ¿por qué no escribir una función que maneje exponentes negativos de esta manera?

  

Se admite la exp negativa si una   existe un mod de base-1 inverso (ver   mpz_invert en la Sección 5.9 [Número   Funciones teóricas], página 35). Si una   el inverso no existe, entonces existe una división por   el cero es elevado.

Si estás hablando de eso, eso implica teoría de números. La división, o más precisamente la inversa de la multiplicación, solo existe en ciertas condiciones. No recuerdo exactamente las reglas, pero básicamente dice que la operación de división no funcionará si base-1 mod mod no existe.

Lo que debe hacer depende de lo que quiera que suceda con los bits que se perderán en la operación. Ya que estás tratando con enteros, aumentar a un poder negativo implica división (bueno, reciprocidad), pero GMP ofrece varias formas de division .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top