Как рассчитать 2 ^ -18 с использованием GMP?

Я только что обнаружил, к моему смущению, что кормление отрицательных показателей mpz_pow_ui не очень хорошо работает ("В руководстве написано, что без знака долго, вы знаете.") mpz_pow функции, руководство использует понятия, которые я не понимаю. Например "base^exp mod mod" в следующем:

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.

В следующем коде, что я должен изменить, чтобы он мог обрабатывать отрицательные показатели?

#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;
}

5 ответов

Решение

mpz_t Тип данных может хранить только целые числа, а 2 -18 не является целым числом. Чтобы вычислить это, вы должны будете использовать тип с плавающей точкой mpf_t или тип рационального числа mpq_t,

Я не буду сокращать код для вас, но я дам вам знать, что:

2-n = 1/2n

Таким образом, вы можете просто передать положительный показатель, а затем разделить 1 на это число (и выбрать нецелочисленный тип, такой как mpf_t - mpz_t тип является целым, поэтому не может представлять реальные числа, такие как 2-18).

Я не знаю много о GMP, но:

2 ^ -18

эквивалентно:

1 / (2 ^ 18)

Так почему бы не написать функцию, которая обрабатывает отрицательные показатели таким образом?

Отрицательный exp поддерживается, если существует обратный мод base-1 (см. Mpz_invert в Разделе 5.9 [Теоретические функции чисел], стр. 35). Если обратного не существует, то делится на ноль.

Если вы говорите об этом, это касается теории чисел. Деление, или, точнее, обратное умножение, существует только при определенных условиях. Я точно не помню правила, но в основном это говорит о том, что операция деления не будет работать, если мод мода base-1 не существует.

Что вам нужно сделать, зависит от того, что вы хотите, чтобы произошло с битами, которые будут потеряны в операции. Поскольку вы имеете дело с целыми числами, возведение в отрицательную степень подразумевает деление (ну, взаимность), но GMP предлагает несколько форм деления.

Другие вопросы по тегам